Monday, October 15, 2012

C#: Extension Methods


Introduction:
Recently I got a chance of working on extension methods and explored some of the use cases of same.  Extension methods were introduced in C# 3.0

Extension methods allow us to add functionality to existing types without modifying them.  We can add functionality to inbuilt type (string) or any custom type. Extension methods are static and should be placed in static class. Although extension methods are static but they are called as an instance method.

Example:
Following is the example of an Extension method counting number of uppercase letters in a string.
namespace Blog
{
    public static class Extension
    {
public static int CountUpper(this string str)      
{
            int intCount = 0;

            for (int index = 0; index < str.Length; index++)
            {
                    if (char.IsUpper(str[index]))
                   {
                          intCount++;
                   }
            }
            return charcount.Count();
}
     }
}

Here is the calling of this extension method:
string s = "Hello Extension";
int i = s. CountUpper();

After compilation it will be as follows:

Extension. CountUpper(s);


Facts and Rules:
1.  First parameter is preceded by this
2.  First parameter defines the type on which extension method can be called.
3.  Extension method must be public and static.
4.  Class having extension method must also be static.
5.  Namespace Blog needs to be imported to access the extension method.
6.  At compile time, all extension methods are translated into static methods.

Chaining
We can chain extension methods as well.

namespace Blog
{
    public static class Extension
    {
public static int Action1(this string str) {….}    
public static int Action2(this string str) {….}
    }
}

These can be called as follows:
s. Action1().Action2();
OR
s. Action2().Action3();

Most commonly used extension methods are LINQ queries which are developed on existing type.

Extension method vs Instance methods:
We can use extension method to extend the functionality of a type but cannot override existing functionality. If extension method has same name as instance method then extension method will never be called.

    public static class Extension
    {
public static int IndexOf(this string str) {….}    
    }

IndexOf extension method will never be called as string class already has an inbuilt IndexOf method. Although we cannot have extension method with same name as type’s existing method but can overload extension methods to provide new functionality.

Friday, October 12, 2012

C# : Access internal methods/classes of an Assembly


Microsoft introduced the new attribute InternalsVisibleTo which you can define inside your AssemblyInfo.cs file. It works like a friend class in C++, so after doing this you can access your internal methods.

Assembly without strong name:

[assembly: InternalsVisibleTo("AssemblyName")]

Strong named assembly then define it with the key.

[assembly: InternalsVisibleTo("AssemblyName, PublicKey=xxxxxxx")]

We used this to access internal methods/classes for writing unit test cases.

Monday, October 8, 2012

C# 4.0 : Named arguments and Optional parameter


Along with Optional Parameter C# 4.0 introduces a new feature of Named parameters as well, where we can provide a value of parameters with their name. We can pass arguments in any order, there is no need to remember the order of parameters.

Example1: Named Parameters
public void Hello(string strGreeting, string strWin)
{
     Console.WriteLine(strGreeting + “ ” + strWin);
}

Irrespective of the order of parameters, output of both the method calls will be same here.

Hello(strGreeting: "Hello!", strWin: "India");
Hello(strWin: "India", strGreeting: "Hello!");
Hello("Hello!", strWin: "India");

Output: 
Hello! India
Hello! India


Example2: Named and Optional

Named arguments are generally used with optional parameters.

public void Hello(string strGreeting = "Hello!", string strWin= "Winshuttle")
{
       Console.WriteLine(strGreeting + " " + strWin);
}

Hello();
Hello("Hello!");
Hello("Hello!", "Winshuttle");
Hello(strGreeting: "Hello!", strWin: "Winshuttle");
Hello(strWin: "Winshuttle", strGreeting: "Hello!");
Hello("Hello!", strWin: "Winshuttle");

Output: 
Hello! Winshuttle
Hello! Winshuttle
Hello! Winshuttle
Hello! Winshuttle
Hello! Winshuttle

Note:
  • Named argument must come after all positional parameters.
  • These both are useful when we call COM API’s.
  • We can omit method overloads using these features.

C# 4.0 : Optional Parameters


C# 4.0 has introduced a new feature of optional parameters, where we can provide a default value of a parameter in its declaration itself. Default parameters can be applied to methods, constructors, indexers or delegate.

Example1:
public void Hello(string strGreeting = "Hello!")
{
     Console.WriteLine(strGreeting);
}

Here pstrGreeting is an optional parameter and can be omitted during method call.

Hello();
Output:  Hello!

If we do not supply value of pstrGreeting, it will be default to “Hello!”

Example2:

void Hello (string pstrGreeting = “Hello!”, string strWin = “Winshuttle”)
{
                Console.WriteLine(pstrGreeting + “ “ + strWin);
}

Outputs for different versions are as follows:
Hello();                                  // Hello! Winshuttle
Hello("HELLO");                  // HELLO Winshuttle
Hello("HELLO", "INDIA");   // HELLO INDIA

Note:
  • If we add a default parameter to a public method then any depended assembly will also required recompilation.
  • Default value must be specified by a constant expression.
  • Optional parameter can’ be ref or out.
  • Mandatory parameters must come before optional except params (always come last).
  • String.Empty cannot be used as default value as it is not a compile-time constant. It is a static property defined in the string class.