
Pro CSharp 2008 And The .NET 3.5 Platform [eng]
.pdf
432 CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES
Extending Interface Types via Extension Methods
At this point, you have seen how to extend classes (and, indirectly, structures that follow the same syntax) with new functionality via extension methods. To wrap up our investigation of C# 2008 extension methods, allow me to point out that it is possible to extend an interface type with new methods; however, the semantics of such an action are sure to be a bit different from what you might expect.
Create a new Console Application named InterfaceExtensions and define a simple interface type (IBasicMath) that contains a single method named Add(). Next, implement this interface on a class type (MyCalc) in a fitting manner. For example:
//Define a normal CLR interface in C#. interface IBasicMath
{
int Add(int x, int y);
}
//Implementation of IBasicMath.
class MyCalc : IBasicMath
{
public int Add(int x, int y)
{
return x + y;
}
}
Now, assume you do not have access to the code definition of IBasicMath, but wish to add a new member (such as a subtraction method) to expand its behavior. You might attempt to author the following extension class to do so:
static class MathExtensions
{
// Extend IBasicMath with subtraction method? public static int Subtract(this IBasicMath itf,
int x, int y);
}
However, this will result in compile-time errors. When you extend an interface with new members, you must also supply an implementation of these members! This seems to fly in the face of the very nature of interface types, as interfaces do not provide implementations, only definitions. Nevertheless, we are required to define our MathExtensions class as follows:
static class MathExtensions
{
//Extend IBasicMath this method and this
//implementation.
public static int Subtract(this IBasicMath itf, int x, int y)
{
return x - y;
}
}
At this point, you might assume you could create a variable of type IBasicMath and directly invoke Subtract(). Again, if this were possible (which it is not), this would destroy the nature of
.NET interface types. In reality, what we have actually said here is “Any class in my project implementing IBasicMath now has a Subtract() method, implemented in this manner.” As before, all the

CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES |
433 |
basic rules apply, therefore the namespace defining MyCalc must have access to the namespace defining MathExtensions. Consider the following Main() method:
static void Main(string[] args)
{
Console.WriteLine("***** Extending an interface *****\n");
//Call IBasicMath members from MyCalc object.
MyCalc c = new MyCalc();
Console.WriteLine("1 + 2 = {0}", c.Add(1, 2)); Console.WriteLine("1 - 2 = {0}", c.Subtract(1, 2));
//Can also cast into IBasicMath to invoke extension.
Console.WriteLine("30 - 9 = {0}", ((IBasicMath)c).Subtract(30, 9));
//This would NOT work!
//IBasicMath itfBM = new IBasicMath();
//itfBM.Subtract(10, 10);
Console.ReadLine();
}
That wraps up our examination of C# 2008 extension methods. Remember that this particular language feature can be very useful whenever you wish to extend the functionality of a type, even if you do not have access to the original source code, for the purposes of polymorphism. And, much like implicitly typed local variables, extension methods are a key element of working with the LINQ API. As you will see in the next chapter, numerous existing types in the base class libraries have been extended with new functionality (via extension methods) to allow them to integrate with the LINQ programming model.
■Source Code The InterfaceExtension project can be found under the Chapter 13 subdirectory.
Understanding Partial Methods
Since the release of .NET 2.0, we have been able to build partial class definitions using the partial keyword (see Chapter 5). Recall that this bit of syntax allows us to partition the full implementation of a type across multiple code files (or other locations, such as in memory). As long as each aspect of the partial type has the same fully qualified name, the end result is a single “normal” compiled class type in the assembly being constructed.
C# 2008 widens the scope of the partial keyword in that it can now be applied on the method level. In a nutshell, this allows you to prototype a method in one file, yet implement it in another file. If you have a C++ background, this might remind you of the concept of a C++ header/implementation file; however, C# partial methods have a number of important restrictions:
•Partial methods can only be defined within a partial class.
•Partial methods must return void.
•Partial methods can be static or instance level.
•Partial methods can have arguments (including parameters modified by this, ref, or params—but not with the out modifier).
•Partial methods are always implicitly private.

434 CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES
Even stranger is the fact that a partial method may or may not be emitted into the compiled assembly!
A First Look at Partial Methods
To see the implications of defining a partial method, create a new Console Application project named PartialMethods. Now, define a new class named CarLocator within a C# file named
CarLocator.cs:
// CarLocator.cs partial class CarLocator
{
//This member will always be part of the
//CarLocator class.
public bool CarAvailableInZipCode(string zipCode)
{
//This call *may* be part of this method
//implementation.
VerifyDuplicates(zipCode);
//Assume some interesting database logic
//here...
return true;
}
// This member *may* be part of the CarLocator class! partial void VerifyDuplicates(string make);
}
Notice that the VerifyDuplicates() method has been defined with the partial modifier and does not define a method body within this file. Also notice that the CarAvailableInZipCode() method is making a call to VerifyDuplicates() within its implementation.
If you were to compile this application as it now stands and open the compiled assembly into a tool such as ildasm.exe or reflector.exe, you will find no trace of the VerifyDuplicates() method in the CarLocator class, and no trace of the call to VerifyDuplicates() within CarAvailableInZipCode()! Given the project as it now stands, you really authored the following definition of the CarLocator class as far as the compiler is concerned:
internal class CarLocator
{
public bool CarAvailableInZipCode(string zipCode)
{
return true;
}
}
The reason for this strange stripping away of code has to do with the fact that our partial VerifyDuplicates() method was never given a true implementation. If we were to now add a new file to our project (named perhaps CarLocatorImpl.cs) that defined the remainder of our partial method:
// CarLocatorImpl.cs partial class CarLocator
{
partial void VerifyDuplicates(string make)
{
// Assume some expensive data validation

CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES |
435 |
// takes place here...
}
}
We would now find that the full scope of the CarLocator class is taken into account at compile time (as shown in the following approximate C# code):
internal class CarLocator
{
public bool CarAvailableInZipCode(string zipCode)
{
this.VerifyDuplicates(zipCode); return true;
}
private void VerifyDuplicates(string make)
{
}
}
As you can see, when a method is defined with the partial keyword, the compiler will determine if it should be emitted into the assembly based on whether the method has a method body or is simply an empty signature. If there is no method body, all traces of the method (invocations, metadata descriptions, prototypes) are stripped out during the compilation cycle.
In some ways, C# partial methods are a strongly typed version of conditional code compilation (via the #if, #elif, #else, and #endif preprocessor directives; see Chapter 12). The major difference, however, is that a partial method will be completely ignored during the compilation cycle (regardless of build settings) if there is not a supporting implementation.
Uses of Partial Methods
Given the restrictions that come with a partial method, most notably the fact that they must be implicitly private and always return void, it is hard to see many useful applications of this new language feature. Truth be told, out of all of the language features found with C# 2008, partial methods will more likely than not be the least used among them.
In the current example, the VerifyDuplicates() method was marked as partial for illustrative purposes; however, imagine that this method, if implemented, had to perform some very intensive calculations.
By marking this method with the partial modifier, other class builders have the option of providing implementation details if they so choose. In this case, partial methods provide a cleaner solution than using preprocessor directives, supplying “dummy” implementations to virtual methods or throwing NotImplementedException objects.
The most common use of this syntax is to define what are termed lightweight events. This technique enables class designers to provide method hooks, similar to event handlers, that developers may choose to implement or not. As a naming convention, such lightweight event-handling methods take an On prefix, for example:
// CarLocator.EventHandler.cs partial class CarLocator
{
public bool CarAvailableInZipCode(string zipCode)
{
...
OnZipCodeLookup(zipCode); return true;
}

436 CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES
...
// A "lightweight" event handler.
partial void OnZipCodeLookup(string make);
}
If a class builder wishes to be informed when the CarAvailableInZipCode() method has been called, they can provide an implementation of the OnZipCodeLookup() method. If they do not care, they simply do nothing.
■Source Code The PartialMethods project can be found under the Chapter 13 subdirectory.
Understanding Object Initializer Syntax
C# 2008 offers a new way to hydrate the state of a new class or structure variable termed 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.
To see this new syntax in action, create a new Console Application named ObjectInitializers. Now, consider the various geometric types created over the course of this text (Point, Rectangle, Hexagon, etc.). For example, recall our simple Point type (which did not make use of C# 2008 automatic properties):
public class Point
{
private int xPos, yPos;
public Point(int x, int y) { xPos = x; yPos = y; } public Point(){}
public int X
{
get { return xPos; } set { xPos = value; }
}
public int Y
{
get { return yPos; } set { yPos = value; }
}
public override string ToString()
{ return string.Format("[{0}, {1}]", xPos, yPos); }
}
Under C# 2008, we could now make Points using any of the following approaches:
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Object Init Syntax *****\n");
// Make a Point by setting each property manually...
Point firstPoint = new Point();

CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES |
437 |
firstPoint.X = 10; firstPoint.Y = 10;
//...or make a Point via a custom constructor...
Point anotherPoint = new Point(20, 20);
//...or make some Point types using the new object init syntax. var yetAnotherPoint = new Point { X = 30, Y = 30 };
Point finalPoint = new Point { X = 30, Y = 30 }; Console.ReadLine();
}
The final two Point types (one of which is implicitly typed, just for the purpose of illustration) are not making use of a custom type constructor (as one might do traditionally), but are rather setting values to the public X and Y properties. Behind the scenes, the type’s default constructor is invoked, followed by setting the values to the specified properties. To this end, yetAnotherPoint and finalPoint are just shorthand notations for the syntax used to create the firstPoint variable (going property by property).
Now recall that this same syntax can be used to set public fields of a type, which Point currently does not support. However, for the sake of argument, assume that the xPos and yPos member variables have been declared publicly. We could now set values to these fields as follows:
var p = new Point {xPos = 2, yPos = 3};
Given that Point now has four public members, the following syntax is also legal. However, try to figure out the actual final values of xPos and yPos:
var p = new Point {xPos = 2, yPos = 3, X = 900};
As you might guess, xPos is set to 900, while yPos is the value 3. From this, you can correctly infer that object initialization is performed in a left-to-right manner. To clarify, the previous initialization of p using standard object constructor syntax would appear as follows:
Point p = new Point(); p.xPos = 2;
p.yPos = 3; p.X = 900;
Calling Custom Constructors with Initialization Syntax
The previous examples initialized Point types by implicitly calling the default constructor on the type:
// Here, the default constructor is called implicitly.
Point finalPoint = new Point { X = 30, Y = 30 };
If you wish to be very clear about this, it is permissible to explicitly call the default constructor as follows:
// Here, the default constructor is called explicitly.
Point finalPoint = new Point() { X = 30, Y = 30 };
Do be aware that when you are constructing a type using the new initialization syntax, you are able to invoke any constructor defined by the class or structure. Our Point type currently defines a two-argument constructor to set the (x, y) position. Therefore, the following Point declaration results in an X value of 100 and a Y value of 100, regardless of the fact that our constructor arguments specified the values 10 and 16:

438 CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES
// Calling a custom constructor.
Point pt = new Point(10, 16) { X = 100, Y = 100 };
Given the current definition of our Point type, calling the custom constructor while using initialization syntax is not terribly useful (and more than a bit verbose). However, if our Point type provides a new constructor that allows the caller to establish a color (via a custom enumeration named PointColor), the combination of custom constructors and object initialization syntax becomes clear. Assume we have updated Point as follows:
public enum PointColor
{ LightBlue, BloodRed, Gold }
public class Point
{
public int xPos, yPos; private PointColor c;
public Point(PointColor color)
{
xPos = 0; yPos = 0; c = color;
}
public Point(){}
public Point(int x, int y)
{
xPos = x; yPos = y; c = PointColor.Gold;
}
...
public override string ToString()
{ return string.Format("[{0}, {1}, Color = {2}]", xPos, yPos, c); }
}
With this new constructor, we can now create a golden point (positioned at 90, 20) as follows:
// Calling a more interesting custom constructor with init syntax.
Point goldPoint = new Point(PointColor.Gold){ X = 90, Y = 20 }; Console.WriteLine("Value of Point is: {0}", goldPoint);
Initializing Inner Types
Recall from Chapter 6 that the “has-a” relationship allows us to compose new types by defining member variables of existing types. For example, assume we now have a Rectangle class, which makes use of the Point type to represent its upper-left/bottom-right coordinates:
public class Rectangle
{
private Point topLeft = new Point(); private Point bottomRight = new Point();
public Point TopLeft
{
get { return topLeft; } set { topLeft = value; }
}
public Point BottomRight
{

CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES |
439 |
get { return bottomRight; } set { bottomRight = value; }
}
public override string ToString()
{
return string.Format("[TopLeft: {0}, {1}, BottomRight: {2}, {3}]", topLeft.X, topLeft.Y, bottomRight.X, bottomRight.Y);
}
}
Using object initialization syntax, we could create a new Rectangle type and set the inner Points as follows:
// Create and initialize a Rectangle.
Rectangle myRect = new Rectangle
{
TopLeft = new Point { X = 10, Y = 10 }, BottomRight = new Point { X = 200, Y = 200}
};
Again, the benefit of this new syntax is that it basically decreases the number of keystrokes (assuming there is not a suitable constructor). Here is the traditional approach to establishing a similar Rectangle:
// Old-school approach.
Rectangle r = new Rectangle(); Point p1 = new Point();
p1.X = 10; p1.Y = 10; r.TopLeft = p1;
Point p2 = new Point(); p2.X = 200;
p2.Y = 200; r.BottomRight = p2;
Understanding Collection Initialization
Closely related to the concept of object initialization syntax is collection initialization. This syntax makes it possible to populate a container (such as ArrayList or List<T>) 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<int> myGenericList = new List<int> { 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 };
If your container is managing a collection of object types, you can blend object initialization syntax with collection initialization syntax to provide the following:
List<Point> myListOfPoints = new List<Point>
{
new Point { X = 2, Y = 2 }, new Point { X = 3, Y = 3 },


CHAPTER 13 ■ C# 2008 LANGUAGE FEATURES |
441 |
While building such a class is not rocket science, it can be rather labor intensive if you are attempting to encapsulate more than a handful of members (although automatic properties do help in this regard). As of C# 2008, we are now provided with a massive shortcut for this very situation termed anonymous types, which in many ways is a natural extension of C#’s anonymous methods syntax (examined in Chapter 11).
When you define an anonymous type, you do so by making use of the new var keyword in conjunction with the object initialization syntax you have just examined. To illustrate, create a new Console Application named AnonymousTypes. Now, update Main() with the following anonymous class, which models a simple car type:
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Anonymous Types *****\n");
// Make an anonymous type representing a car.
var myCar = new { Color = "Bright Pink", Make = "Saab", CurrentSpeed = 55 };
// Now show the color and make.
Console.WriteLine("My car is a {0} {1}.", myCar.Color, myCar.Make); Console.ReadLine();
}
Again note that the myCar variable must be implicitly typed, which makes good sense, as we are not modeling the concept of an automobile using a strongly typed class definition. 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.
Also notice that we have to specify (using object initialization syntax) the set of properties that model the data we are attempting to encapsulate. Once defined, these values can then be obtained using standard C# property invocation syntax.
The Internal Representation of Anonymous Types
All anonymous types are automatically derived from System.Object, and therefore support each of the members provided by this base class. Given this, we could invoke ToString(), GetHashCode(), Equals(), or GetType() on the implicitly typed myCar object. Assume our Program class defines the following static helper function:
static void ReflectOverAnonymousType(object obj)
{
Console.WriteLine("obj is an instance of: {0}", obj.GetType().Name); Console.WriteLine("Base class of {0} is {1}",
obj.GetType().Name, obj.GetType().BaseType);
Console.WriteLine("obj.ToString() = {0}", obj.ToString()); Console.WriteLine("obj.GetHashCode() = {0}", obj.GetHashCode()); Console.WriteLine();
}
Now assume we invoke this method from Main(), passing in the myCar object as the parameter:
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Anonymous types *****\n");
// Make an anonymous type representing a car.
var myCar = new {Color = "Bright Pink", Make = "Saab", CurrentSpeed = 55};