Wednesday, October 8, 2008

New Features of C#.NET 2008 Language (Part 2)

This is a second part of my post "New Features of C#.NET 2008 Language (Part 1)".


(4) Extension Methods:

As we know, once a type is defined and compiled into a .NET assembly, its definition is, more or less, final. The only way to add new members, update members or remove members is to recode and recompile the code base into an updated assembly.

In C# 2008, using extension methods we can add new functionality to existing complied class without directly updating that class.

This technique can be quite helpful when you need to inject new functionality into classes for which you do not have an existing code base. Using extension methods, you can add functionality to precompiled classes while providing the illusion these methods were there all along.

Restrictions:

(a) Extension methods must be defined within a static class and therefore each extension method must also be declared with the static keyword.
(b) All extension methods are marked as such by using the this keyword as a modifier on the first (and only the first) parameter of the method.
(c) Every extension method can be called either from the correct instance in memory
or statically via the defining static class!

Example:

static class MyExtensions
{
// This method allows any object to display the assembly
// it is defined in.
public static void DisplayDefiningAssembly(this object obj)
{
Console.WriteLine("{0} lives here:\n\t->{1}\n", obj.GetType().Name,
Assembly.GetAssembly(obj.GetType()));
}

// This method allows any integer to reverse its digits.
// For example, 56 would return 65.
public static int ReverseDigits(this int i)
{
// Translate int into a string, and then
// get all the characters.
char[] digits = i.ToString().ToCharArray();
// Now reverse items in the array.
Array.Reverse(digits);
// Put back into string.
string newDigits = new string(digits);
// Finally, return the modified string back as an int.
return int.Parse(newDigits);
}
}

Now that we have these extension methods, so all objects have a new method named DisplayDefiningAssembly(), while System.Int32 class have method named ReverseDigits().

// The int has assumed a new identity!
int myInt = 1234;
myInt.ReverseDigits();

// So has the DataSet!
System.Data.DataSet ds = new System.Data.DataSet();
ds.DisplayDefiningAssembly();


(5) Object Initializer Syntax:
Using this technique, it is possible to create a new type variable and assign a slew of properties and/or public fields in a few lines of code. Syntactically, an object initializer consists of a comma-delimited list of specified values, enclosed by the { and } tokens. Each member in the initialization list maps to the name of a public field or public property of the object being initialized.

Example:
Class A
{
private int customerId;
private string customerName;
public CustomerId
{
Get { return customerId; }
Set { customerId = value; }
}
public CustomerName
{
Get { return customerName; }
Set { customerName = value; }
}
}

Now, you can declare object of class A as follow:
A objA = new A{CustomerId = 1, CustomerName = “XYZ};

Collection Initialization:

This syntax makes it possible to populate a container (such as ArrayList or List) with items using a syntax that models that of a simple array. Consider the following examples:


// Init a standard array.
int[] myArrayOfInts = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Init a generic List<> of ints.
List myGenericList = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Init an ArrayList with numerical data.
ArrayList myList = new ArrayList { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };


(6) Anonymous Types:

There are other times in programming when you would like to define a class simply to model a set of encapsulated (and somehow related) data points without any associated methods, events, or other custom functionality. Furthermore, what if this type is only used internally to your current application and it’s not intended to be reused? If you need such a “temporary” type, earlier versions of C# would require you to nevertheless build a new class definition by hand:

internal class MyClass
{
// Define a set of private member variables...
// Make a property for each member variable...
}

As of C# 2008, we are now provided with a massive shortcut for this very situation termed anonymous types, When you define an anonymous type, you do so by making use of the new var keyword in conjunction with the object initialization syntax. E.g.

var myCust = new {customerId = 1, customerName = “XYZ”};

At compile time, the C# compiler will autogenerate a uniquely named class on our behalf. Given the fact that this class name is not visible from C#, the use of implicit typing using the var keyword is mandatory.

Limitations of anonymous type:

• You don’t control the name of the anonymous type.
• Anonymous types always extend System.Object.
• The fields and properties of an anonymous type are always read-only.
• Anonymous types cannot support events, custom methods, custom operators, or custom overrides.
• Anonymous types are always implicitly sealed.
• Anonymous types are always created using the default constructor.

No comments: