Thursday, November 15, 2007

Design Patterns

Creational patterns
These patterns have to do with class instantiation. They can be further divided into class-creation patterns and object-creational patterns. While class-creation patterns use inheritance effectively in the instantiation process, object-creation patterns use delegation to get the job done.
Abstract Factory groups object factories that have a common theme.
Builder constructs complex objects by separating construction and representation.
Factory Method creates objects without specifying the exact class to create.
Prototype creates objects by cloning an existing object.
Singleton restricts object creation for a class to only one instance.
Structural patterns
These concern Class and Object composition. They use inheritance to compose interfaces and define ways to compose objects to obtain new functionality.
Adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.
Bridge decouples an abstraction from its implementation so that the two can vary independently.
Composite composes one-or-more similar objects so that they can be manipulated as one object.
Decorator dynamically adds/overrides behaviour in an existing method of an object.
Facade provides a simplified interface to a large body of code.
Flyweight reduces the cost of creating and manipulating a large number of similar objects.
Proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity.
Behavioral patterns
These design patterns are about Class's objects communication. They are specifically concerned with communication between objects.
Chain of responsibility delegates commands to a chain of processing objects.
Command creates objects which encapsulate actions and parameters.
Interpreter implements a specialized language.
Iterator accesses the elements of an object sequentially without exposing its underlying representation.
Mediator allows loose coupling between classes by being the only class that has detailed knowledge of their methods.
Memento provides the ability to restore an object to its previous state (undo).
Observer is a publish/subscribe pattern which allows a number of observer objects to see an event.
State allows an object to alter its behavior when its internal state changes.
Strategy allows one of a family of algorithms to be selected on-the-fly at runtime.
Template method defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior.
Visitor separates an algorithm from an object structure by moving the hierarchy of methods into one object.
PRABHAKAR THALLAPALLI

Wednesday, October 10, 2007

Delegates , Events and Event Handlers in .Net

Delegates , Events and Event Handlers
Delegates are a critical aspect of the Microsoft® .NET Framework and are required learning for many programmers. They will take some time to master, but once you learn how to program with delegates, you'll be thrilled with the possibilities they offer.
Let's dig in. First, you should know that events in the .NET Framework are layered on top of delegates. When you use an event-driven application framework such as Windows® Forms or ASP.NET, your knowledge of delegates will make you a much stronger developer. Delegates provide the primary means in .NET for executing a method on a secondary thread in an asynchronous fashion. Therefore, delegates open the door to multithreading.
Delegates represent a .NET innovation intended to address application designs that involve callback notifications. First we will see how to implement callbacks using delegates. However, before I jump into programming with delegates, I want to explain why and how callback notifications have been implemented in the past.

Callback Notifications
Application software is often designed around the notion of callbacks. The use of callbacks is a programming technique in which one part of an application sends out notifications to alert other parts of the application whenever something interesting has occurred. To be more specific, a callback is a method that is implemented by one or more handlers and is then executed by a notification source.
Most programmers who use Visual Basic® should be familiar with the concept of callbacks because of the manner in which Visual Basic has always supported event handling. An event handler is a simple example of a callback method. When you write an event handler for the Click event of a command button, you are really writing the implementation for a callback method. However, you are not required to explicitly call the event handler. Instead, the Form class of the Windows Forms framework acts as a notification source because it automatically executes your event handler method at exactly the right time.
It can be helpful to make an analogy to something that might occur in everyday life to fully appreciate the value of a design based on callbacks. Imagine your boss has just assigned you a task. Assume that this task will take several hours to complete and that your boss wants to know the minute that you are finished. It would probably become very annoying if your boss called you on the phone every few minutes to ask if you had finished the task. It would be far more reasonable for you to make the following suggestion to your boss. "Don't call me; I'll call you when I'm finished."
As long as you notify your boss the moment you've completed the task, your boss can react and take whatever actions are appropriate in a timely fashion. As you can imagine, the use of a callback in this particular scenario is going to be more efficient (and far less annoying) than having your boss poll you every few minutes to see if you've finished your work.
If you are using Visual Basic .NET or an earlier version such as Visual Basic 6.0, you can implement a callback design using an interface. For example, you can use an interface to define a callback method. Then you can create a listener class that implements this interface. In doing so, your listener class will provide an implementation for the handler method defined by the interface. Finally, you can design another object to act as a notification source. The notification source object should be designed to track an interface-based reference to a listener object. Once the notification source object has a reference to the listener object, it can execute the handler method whenever it needs to send out callback notification.
C++ programmers have been implementing callbacks in their applications long before the .NET Framework came along. However, a callback in C++ is often implemented without the use of an interface. Instead, it can be implemented using something called a function pointer. While it's not important for you to know the low-level details of how to program using function pointers, it's valuable to understand them at a higher level because of how much influence they have had on the architecture of the .NET Framework.
A function pointer is an in-memory address that points to a method implementation. At the physical level, a function pointer points to a set of instructions that represents the executable logic for a method. To use a function pointer, one part of the application must initialize it to point to a particular method. Another part of an application can then use this function pointer to execute the method to which it points.
Function pointers are useful in C++ because they provide an efficient way to implement a callback between a notification source and a listener. As long as a notification source can obtain a function pointer that points to the implementation for a handler method, it can send out notifications in an anonymous fashion.
When it comes to modeling callbacks, however, the use of function pointers offers a few distinct advantages over the use of interfaces. First, function pointers don't require that a notification source and its listeners agree on the names of callback methods. Second, the use of function pointers can provide a higher degree of granularity than interfaces because you can register handlers to receive callbacks on a method-by-method basis. Function pointers also make it possible to use shared (static) methods in addition to instance methods.


Introducing Delegates
When architects on the .NET team began to design their new framework, they knew they wanted to provide rich support for implementing callbacks. They weighed the pros and cons of implementing callback methods with interfaces versus function pointers. In the end, they decided to create a new hybrid technique that combines the type safety and polymorphism of using interfaces together with the efficiency and flexibility of using function pointers. This new technique involves an innovation known as a delegate.
A delegate is a special kind of type within the programming model of the .NET Framework. The architects of the .NET Framework added delegates to provide a convenient binding mechanism to wire up one or more handler methods to a notification source. As you will see, delegates can be used to implement the same kinds of callback designs that you can implement using interfaces or function pointers. However, a callback design based on a delegate often requires less code and provides more features than a callback design based on an interface or function pointers.
You can define a delegate type in Visual Basic .NET using the Delegate keyword. Each delegate definition you create must include a type name and the calling signature for a handler method. Here's an example of three delegate type definitions:
Delegate Sub BaggageHandler()
Delegate Sub MailHandler(ItemID As Integer)
Delegate Function QuoteOfTheDayHandler(Funny As Boolean) As String
As you can see, you define the calling signature of a delegate type using the standard Visual Basic syntax for method definitions. Like a method, a delegate type must be defined using either the Sub keyword or the Function keyword. A delegate definition is also similar to a method definition in that it can optionally define a parameter list and a return value.
When you compile code that contains a delegate type definition, the Visual Basic .NET compiler does some extra work for you behind the scenes. In particular, the compiler generates a class definition for each delegate type. The class that is generated for each delegate type is a creatable class that inherits from the System.Multicast delegate. Figure 1 shows what the preceding three delegate types look like after compilation from the perspective of ILDASM.EXE.

Figure 1 Delegate Types After Compilation
Take a moment to examine the definition of the delegate type QuoteOfTheDayHandler in Figure 1. You can see that in addition to creating a class that inherits from MulticastDelegate, the Visual Basic .NET compiler has also added a public constructor and three public methods named Invoke, BeginInvoke, and EndInvoke.
The Visual Basic .NET compiler adds a public constructor to each delegate definition to make it a creatable type. The public constructor is the member with the name .ctor. Once you acknowledge that a delegate is a creatable type, it is easier to understand how it's used in an application. Programming with delegates requires creating delegate objects from delegate types. Furthermore, each delegate object must be created in such a way so that it gets initialized to point to a target method implementation. In just a moment, you will see how to do this by writing the code to create a delegate object that gets bound to a target handler method.
In addition to a public constructor, the compiler automatically adds a public method named Invoke whenever it generates a delegate type definition. The Invoke method is supplied so that a notification source can execute the target handler method to which the delegate object is bound. When you call Invoke on a delegate object, it simply forwards the call to the target handler method.
The calling signature for the Invoke method of QuoteOfTheDayHandler matches the calling signature of the delegate type itself. This is always the case with a delegate type definition. The compiler will always generate an Invoke method whose calling signature matches that of the containing delegate type. Any input parameters that you pass in a call to Invoke will be forwarded in the call to the target handler method. If the target handler method has any output parameters or a return value, these values will be returned to the caller of the delegate object's Invoke method.
You have probably also noticed that the definition for type QuoteOfTheDayHandler contains two additional methods generated by the compiler, named BeginInvoke and EndInvoke. These two methods provide a basis for executing a delegate object's target handler method on a separate thread in an asynchronous fashion. The fact that delegates can be used to execute certain tasks asynchronously makes them that much more powerful. However, I will defer a discussion of how to use BeginInvoke and EndInvoke to execute methods asynchronously for a future column.


Creating a Delegate Object
When you want to create a delegate object, you typically use the New operator followed by the name of the delegate type. When you create a delegate object using the New operator, you must provide the information that's needed to bind the new delegate object to the implementation of a target handler method. Let's step through an example using the QuoteOfTheDayHandler delegate.
Before you can create a delegate object, you must determine what handler method you'd like to bind it to. A handler method can be either a shared method or an instance method. Keep in mind that the name of the handler method doesn't really matter. The only requirement is that a handler method be defined with a calling signature that matches the delegate type. For the first example, imagine you have written a class named JennysHandlers that contains a shared method that was written to be a handler method for the QuoteOfTheDayHandler delegate type, as shown in the following code:
Class JennysHandlers
Shared Function GetQuote(ByVal Funny As Boolean) As String
'*** custom handler implementation
End Function
End Class
As you can see, the shared method GetQuote has the correct calling signature to be used with the QuoteOfTheDayHandler delegate. When you want to create a delegate object, you can use the New operator and pass a parameter value with the information that allows the CLR to bind the new delegate object to a target method implementation. The way to accomplish this in Visual Basic .NET is by using the AddressOf operator followed by the method name. For example, you can create a delegate object that is bound to the GetQuote method using the following code:
Dim handler1 As QuoteOfTheDayHandler
handler1 = New QuoteOfTheDayHandler(AddressOf JennysHandlers.GetQuote)
Note that the Visual Basic .NET compiler will generate a compile-time error if the calling signature of the GetQuote method does not match the calling signature of the delegate type QuoteOfTheDayHandler. These compile-time checks are what makes programming with delegates far less error-prone than programming with function pointers. The strongly typed nature of delegates ensures that a notification source and its handler methods all agree on a particular calling signature.
You might remember the AddressOf operator from previous versions of Visual Basic. This operator was introduced in Visual Basic 5.0 to provide a means for passing actual function pointers to low-level functions in the Win32® API. However, the role of AddressOf is different in Visual Basic .NET. Its primary purpose is now to initialize delegate objects.
Note that the Visual Basic .NET language provides a convenient shorthand syntax for creating a delegate object. The previous code sample can be rewritten more concisely:
Dim handler1 As QuoteOfTheDayHandler
handler1 = AddressOf JennysHandlers.GetQuote
As you can see, the call to the New operator can be omitted for convenience. In this example, the Visual Basic .NET compiler is designed to create a new object from the QuoteOfTheDayHandler delegate type and assign a reference to this delegate object back to the variable handler1. What you should see is that whenever the compiler expects a delegate object of type QuoteOfTheDayHandler, you can simply pass the following expression:
AddressOf JennysHandlers.GetQuote
The Visual Basic .NET compiler expands this expression into code that creates a new QuoteOfTheDayHandler object and binds it to the handler method GetQuote. While the longer syntax might make what's actually going on more obvious, you might find the shorthand syntax more concise and easier to write.
Now that you know how to bind a new delegate object to a handler method, it's time to see how to execute the handler method that the delegate object is bound to. You can execute the handler method by simply calling the Invoke method on the delegate object, as shown in the following code:
'*** create and bind delegate object
Dim handler1 As QuoteOfTheDayHandler
handler1 = AddressOf _
JennysHandlers.GetQuote

'*** execute target method
Dim quote As String = _
handler1.Invoke(True)
Note that the call to Invoke in this example requires a single parameter of type Boolean and has a return value based on the String type. When you call Invoke on the delegate object, it forwards the call by executing the target handler method GetQuote. You should also see that the call to Invoke returns the same value that was returned from the call to GetQuote.
Visual Basic .NET also provides you with another convenient shorthand syntax when programming delegates. You have the option of omitting the call to the delegate's Invoke method. If you don't provide an explicit call to Invoke, the Visual Basic .NET compiler will automatically add the call for you. Look at the following lines of code:
'*** this code
Dim quote1 As String = handler1.Invoke(True)

'*** is the same as this code
Dim quote2 As String = handler1(True)
As you can see, the call to Invoke can be made either explicitly or implicitly. When you replace the syntax handler1.Invoke(True) with the syntax handler1(True), the Visual Basic .NET compiler automatically adds the call to Invoke for you. Therefore, you can simply treat a reference variable or a field based on a delegate type as if it were the name of an actual method.
Whether you make calls to the Invoke method explicitly or implicitly comes down to a stylistic preference on your part. It has no effect on your code once it is compiled. Some programmers prefer explicit calls to Invoke because they feel it makes their code easier to read. Others prefer implicit calls to Invoke because this results in a little less typing.
It is interesting to note that the C# compiler doesn't allow for explicit calls to a delegate's Invoke method. Instead, it requires that programmers use the implicit style in which a delegate reference is treated as though it were an actual method name. The C# compiler always adds the call to Invoke during compilation. If you are planning to switch back and forth between Visual Basic .NET and C#, you might consider using the implicit style of calling Invoke because it promotes greater consistency across languages.


Binding a Delegate to an Instance Method
Up to this point you have seen how to bind a delegate object to a shared method. As you already know, this is accomplished using the AddressOf operator followed by the class name together with the shared method name. However, it's also possible to bind a delegate to an instance method. Let's look at a code example so you can see how binding a delegate object to an instance method differs from binding to a shared method.
Instance methods are different from shared methods because they must execute within the context of an object created from the class in which they are defined. Therefore, binding a delegate object to an instance method requires the delegate object to track a target object in addition to tracking its target method implementation. After all, it would not be possible for a delegate object to execute an instance method unless it knew what object to use for the method's execution context.
In order to create a delegate object that is bound to an instance method, you must start by creating or acquiring a reference to an object created from the class that defines the instance method. For example, suppose you have created a class named JerrysQuotes that contains an instance method named NextQuote, as shown in this code snippet:
Class JerrysQuotes
Function NextQuote(ByVal Funny As Boolean) As String
'*** implementation
End Function
End Class
In order to bind a delegate object to the instance method NextQuote, you must first create an object from the class JerrysQuotes. Once you have acquired an object reference, you can create and bind a delegate object to one of its instance methods. You do this by using the AddressOf operator together with the object reference followed by the method name:
Dim quotes As New JerrysQuotes()
Dim handler2 As QuoteOfTheDayHandler = AddressOf quotes.NextQuote
The difference between this example and the previous one involving a shared method is that the delegate object must now keep track of the target object. Figure 2 reveals some of the private implementation details of a delegate object. As you can see, every delegate object contains a private field that holds a function pointer to a method implementation. Delegate objects that are bound to an instance method also track a reference to a target object that will be used when the target instance method is executed.

Figure 2 Implementing Delegate Objects
When you think of how things work at a lower level, a delegate object is really nothing more than a friendly, type-safe wrapper around a function pointer. However, when you think about delegates at a higher level, it's important to see that they open up many possibilities when it comes to designing an application that requires callbacks. Delegates provide a flexible and efficient way to implement a loosely coupled design in which a notification source must send notifications to a set of handler methods.


Conclusion
This month's column has provided you with an introductory look at delegates. As you have seen, delegates were introduced in the .NET Framework to assist designers and programmers with implementing callback notifications. Delegates provide a hybrid technique for implementing callbacks that combine the type safety of using interfaces together with the efficiency and flexibility of using function pointers.
Now you have seen what is required to define a delegate type and how to create a delegate object and initialize it to bind to either a shared method or an instance method. You've also seen how to fire the handler method by calling the Invoke method supplied by the delegate.
In a future column I'll continue this discussion of delegates and will show you how to create a loosely coupled design using a custom delegate type in which a class has been designed to send out callback notifications. I'll also explain how delegates seamlessly support binding a notification source to multiple handler methods through a feature known as multicasting.


Implementing Callbacks with Delegates
Imagine you are designing an application with a class named BankAccount that contains a method named Withdraw. Let's say you want to make it possible for another part of the application to react whenever a BankAccount object experiences a withdrawal of an amount greater than $5000. The starting point for your class might look something like this:
Class BankAccount
Sub Withdraw(ByVal Amount As Decimal)
If (Amount > 5000) Then
'*** send notification to interested parties
End If
'*** perform withdrawal
End Sub
End Class
In this example, a BankAccount object is going to act as a notification source. That means a BankAccount object must provide a way for a listener to express its interest in receiving notifications. In other words, a BankAccount object must allow a listener to register a handler method for a callback. Let's start by defining a new delegate type named LargeWithdrawHandler:
Delegate Sub LargeWithdrawHandler(ByVal Amount As Decimal)
Now it's time to modify the BankAccount class to act as a notification source. I can do this by adding two members. First, I'll add a private field named "handler" defined in terms of the delegate type LargeWithdrawHandler. Second, I will add a method named RegisterHandler that allows other code to register a delegate object to receive callback notifications:
Class BankAccount
Private handler As LargeWithdrawHandler
Sub RegisterHandler(ByVal handler As LargeWithdrawHandler)
Me.handler = handler
End Sub
'*** other class members omitted
End Class
As you can see, the RegisterHandler method accepts a single parameter of type LargeWithdrawHandler. The implementation of RegisterHandler assigns this value to the field named handler so that a BankAccount object can track a delegate object and execute its handler method.
Once the RegisterHandler method has been called with a delegate object, any method within the BankAccount class can execute the handler method by calling Invoke on the registered delegate object. Here's how you execute the Invoke method from within the Withdraw method of the BankAccount class:
Sub Withdraw(ByVal Amount As Decimal)
'*** send notifications if required
If (Amount > 5000) AndAlso (Not handler Is Nothing) Then
handler.Invoke(Amount)
End If
'*** perform withdrawal
End Sub
The Withdraw method conducts a check to make sure the handler field contains a valid reference rather than a value of Nothing. Remember that it will have a value of Nothing until there is a call to RegisterHandler, so you must prevent your code from attempting to execute the Invoke method on an uninitialized reference.
The BankAccount class has been written to send out a delegate-based notification whenever a withdrawal is made for an amount that exceeds $5000. Now let's create a handler method that can be wired up to respond to these notifications. Take a look at the class shown in the following code:
Class AccountHandlers
Shared Sub GetApproval(ByVal Amount As Decimal)
'*** block until manager approves withdrawal amount
End Sub
Shared Sub LogWithdrawToDB(ByVal Amount As Decimal)
'*** write withdrawal info to a database
End Sub
Shared Sub LogWithdrawToFile(ByVal Amount As Decimal)
'*** write withdrawal info to a log file
End Sub
End Class
The GetApproval, LogWithdrawToDB, and LogWithdrawToFile methods have been written with the proper calling signatures so they can serve as handler methods for the notifications sent by a BankAccount object.
Now, let's write a simple application that ties everything together. First, the application must create a BankAccount object. Next, the application must create a delegate object that is bound to a target handler method such as GetApproval. The final step in hooking everything up is to call the RegisterHandler method, passing a reference to the delegate object.
Module MyApp
Sub Main()
'*** create bank account object
Dim acc1 As New BankAccount()
'*** create delegate object and register callback method
acc1.RegisterHandler(AddressOf AccountHandlers.GetApproval)
'*** do something that triggers callback
acc1.Withdraw(5001)
End Sub
End Module
This example doesn't use the New operator when creating a delegate object. Instead, it uses the more convenient shorthand syntax. Since the RegisterHandler method expects a parameter of type LargeWithdrawHandler, you can simply use the AddressOf operator followed by the method name, as shown in the code.
At this point, I have a simple application that performs a callback notification using a delegate. When the Main method calls the Withdraw method on the BankAccount object and passes a parameter value of 5001, the implementation of the Withdraw method uses the delegate object held by the handler field to execute the GetApproval method.
Note that this application provides a good example of a loosely coupled design. The BankAccount class doesn't know or care about what type of handler method is used. It would be very easy to replace the GetApproval handler method with the handler methods LogWithdrawToDB or LogWithdrawToFile. It would also be easy to create another method in a different class and use that one as a callback method instead. From this, you should be able to conclude that a delegate-based design can provide polymorphism in the same fashion as an interface-based design.
There is still one more important design issue that needs to be addressed. The current implementation of BankAccount can only provide callbacks to a single handler method. It would be better if the BankAccount class could be modified to provide callbacks to more than one handler method at a time. Fortunately, delegates provide built-in support for dealing with multiple handler methods through a feature known as multicasting.


Multicasting
Every delegate type has built-in support for dealing with multiple handler methods. Delegate types gain this support by inheriting from the MulticastDelegate class that's defined in the System namespace. The benefit of multicasting is that you can combine several handler methods in a list so they are all bound to a single delegate object. When Invoke is called on the delegate object, the MulticastDelegate class provides the code to execute every handler method in the list.
An example should help you see exactly how this works. Let's say you'd like to bind two different handler methods to a single delegate object. You can accomplish this by calling a shared method of the System.Delegate class, Combine. If you call the Combine method and pass two delegate objects, this method will return a new delegate object that is a multicast of the other two. Here's an example of taking the handler methods for two different delegate objects and combining them into a multicast delegate object:
'*** create two individual delegates
Dim handler1, handler2 As LargeWithdrawHandler
handler1 = AddressOf AccountHandlers.GetApproval
handler2 = AddressOf AccountHandlers.LogWithdrawToDB

'*** combine delegates into multicast delegate
Dim result As [Delegate] = [Delegate].Combine(handler1, handler2)

'*** convert reference to LargeWithdrawHandler type
Dim handlers As LargeWithdrawHandler
handlers = CType(result, LargeWithdrawHandler)

'*** execute handler methods in multicast list
handlers.Invoke(5001)
Please take a look at the square brackets that have been placed around the name of the [Delegate] class. They are required because Delegate is also a keyword. The brackets are used as escape characters to tell the Visual Basic® .NET compiler that you intend to use Delegate as a class name.
The call to Combine returns a reference to a newly created multicast delegate object. Note that the Combine method has a generic return type of Delegate that must be converted to the more specific delegate type, LargeWithdrawHandler. This is only required if you want to call the Invoke method.
Let's take a moment to discuss how multicast delegates are implemented. A multicast delegate is simply a linked list of delegate objects. The private implementation of each delegate object contains a field designed to hold a reference to the previous delegate object in the list. You might think it would be more intuitive if a delegate held a reference to the next delegate in the list as opposed to the previous delegate. However, the multicast delegate design uses the notion of the previous delegate because of the sequence in which the handler methods are executed. The reason that each delegate object tracks a previous delegate will be explained in more detail later in this column.
When you have created a multicast delegate that contains multiple handler methods, the delegate at the head of the list holds a reference to the previous delegate. That delegate also holds a reference to the previous delegate. For the delegate object at the tail of the list, the field for the previous delegate will have a value of Nothing. As you will see, the position in which a delegate object is placed in the list is important.
When you call Combine, it links two or more delegate objects together and returns a reference to the delegate object at the head of the list. Note that the previous example called the overloaded implementation of Combine that accepts two delegate parameters. This implementation of Combine creates a multicast list that places the delegate object passed as the second parameter at the head. For example, in the preceding code example the delegate at the head of the list is bound to the LogWithdrawToDB method. This delegate object contains a private field that references the previous delegate object that's bound to the GetApproval method.
Note that there is another overloaded version of Combine which accepts an array of delegate objects. When you pass an array of delegate objects to the Combine method, the method places the first delegate object in the array at position 0, at the head of the list. You can call whichever overloaded version of Combine you'd like. Just make sure you pay attention to how each delegate object is being placed in the list. You have control over which handler methods get executed first.
When you call Invoke on the delegate object that's at the head of the list, the MulticastDelegate class provides the code that's needed to enumerate through the list and execute the Invoke method of each delegate object in a chain. It's important to observe that the execution of individual handler methods proceeds in a serialized and synchronous fashion. You should also take note of which handler methods are executed first.
The delegate object at the head of a multicast list does not execute its handler method until after it has called the Invoke method on the previous delegate. This is why the multicast delegate design pattern refers to it as the previous delegate object as opposed to the next delegate object. You should see that control passes from the delegate object at the head of the list to the delegate object at the tail before any handler methods are executed.
The delegate object at the tail of a multicast list always executes its handler method first. Therefore, execution always occurs from back to front. You should observe that the delegate object at the head of the multicast list always executes its handler last. In my example involving a multicasting of two delegate objects, the GetApproval method is going to execute before the LogWithdrawToDB method.


Callbacks with a Multicast Delegate
Now let's revisit the example involving the BankAccount class and add support for multicasting. I'm going to modify the class implementation so that a BankAccount object can make callbacks to a list of handler methods. See the class definition in Figure 1.
First, you should notice that the handler field has been renamed to "handlers" to signify that the field can be used to hold a reference to a multicast delegate object. However, this is nothing more than a renaming issue since the field is still based on the LargeWithdrawHandler delegate type.
The implementation of the RegisterHandler method has also been updated to support multicasting. The implementation of RegisterHandler now calls the Combine method to add the new delegate object to the existing list of delegate objects. Note that the implementation of RegisterHandler passes the new delegate object as the second parameter in its call to Combine. That means the new delegate object will become the head of the list and will, therefore, be executed last in the chain. If you'd prefer, you could easily rewrite RegisterHandler to place a new handler method at the tail of the multicast list where it would execute before any handler method that was previously registered:
Sub RegisterHandler(ByVal handler As LargeWithdrawHandler)
'*** add new handler to tail of multicast list
Dim NewList As [Delegate] = [Delegate].Combine(handler, handlers)
handlers = CType(NewList, LargeWithdrawHandler)
End Sub
You might have also observed that the Withdraw method did not require any modifications other than updating the name of the handler field to "handlers". The call to Invoke is made in the exact same way as before. This illustrates one of the most valuable aspects of using multicast delegates. A multicast delegate doesn't have to be concerned with how many target methods are bound to a delegate object. A notification source simply calls Invoke and every handler method is automatically executed.
Now that the BankAccount class has been updated to support multicasting, the application can be rewritten to register three different handler methods to respond to large withdrawal notifications, as shown in the following code:
Sub Main()
'*** create bank account object
Dim acc1 As New BankAccount()
'*** create register handler methods
acc1.RegisterHandler(AddressOf AccountHandlers.GetApproval)
acc1.RegisterHandler(AddressOf AccountHandlers.LogWithdrawToDB)
acc1.RegisterHandler(AddressOf AccountHandlers.LogWithdrawToFile)
'*** do something that triggers callback
acc1.Withdraw(5001)
End Sub
You should see from this design that multicasting allows you to place the handler methods so they execute in a predictable sequence. Figure 2 gives a high-level view of how things are laid out. The GetApproval method will execute first because it has been placed at the tail of the list. Next, the LogWithdrawFromDB method will execute. Since the LogWithdrawToFile method was registered last, it will be placed at the head of the list and, consequently, will execute last.

Figure 2 Multicast Delegate Executing Handlers
Figure 3 shows a complete application based on the design I just walked though. Before moving on, you should understand what's been created here with delegates: a loosely coupled design for implementing callbacks with support for multicasting. It would be easy to further customize this application by creating even more handler methods and using delegates to register them.


Calling the GetInvocationList Method
In many cases, a notification source can simply call Invoke to execute all the target handler methods associated with a multicast delegate object. However, there are other times when you need more control. For example, you might need to determine how many target handler methods have been added to a multicast delegate list. You also might be required to write code that can gracefully deal with the exceptions thrown by handler methods in the list.
The Delegate class provides a public instance method named GetInvocationList. When you call this method on a multicast delegate, it returns an array of references to individual delegate objects. This array makes it possible to determine how many handler methods are currently bound to a multicast delegate:
'*** determine number of target handler methods
Dim HandlerCount As Integer = handlers.GetInvocationList().Length
A call to GetInvocationList also makes it relatively simple to enumerate through the individual delegate objects and explicitly execute their handler methods one at a time. Since a call to GetInvocationList returns an array of references to delegate objects, it makes it easy to structure your code to enumerate through the delegate objects using a For Each loop:
Sub Withdraw(ByVal Amount As Decimal)
'*** send notifications if required
If Not (Amount > 5000) AndAlso (Not handlers Is Nothing) Then
Dim handler As LargeWithdrawHandler
For Each handler In handlers.GetInvocationList()
handler.Invoke(Amount)
Next
End If
'*** perform withdrawal
End Sub
The code you've just seen doesn't really provide any more control than executing the Invoke method on the handlers field. So you might be asking why you would ever need to call GetInvocationList to enumerate through the delegate objects in the list. One reason is that you might need more control if one of the handler methods throws an exception during its execution.
Let's look at an example. Imagine you are holding onto a multicast delegate object that is bound to 10 handler methods. What happens if you call Invoke, and the seventh handler method throws an exception? The first six handler methods have already executed successfully. The exception thrown by the seventh handler causes the Invoke method to terminate unexpectedly. Therefore, the eighth, ninth, and tenth handler methods never execute at all.
The problem is that there's really no way to tell which handler methods executed successfully, which handler method failed, and which handler methods were never executed. You'll have more control if you restructure your code to explicitly call the Invoke method on each delegate object within a Try block:
Dim handler As LargeWithdrawHandler
For Each handler In handlers.GetInvocationList()
Try
handler.Invoke(Amount)
Catch ex As Exception
'*** deal with exception and continue
End Try
Next
A second reason you might need to call GetInvocationList and enumerate through each delegate object individually is that it makes it possible to retrieve return values and output parameters from more than one handler method. If you call Invoke on a multicast delegate object and it involves an output parameter or a return value, the results you get are somewhat arbitrary. The output parameter and the return value you receive are the ones supplied by the last handler method to execute. Remember, that's the delegate object at the head of the list. However, you can capture a separate output parameter and return value for each handler method if you write the extra code to enumerate through the list and explicitly call Invoke on each delegate object.
Note that GetInvocationList returns an array that represents a snapshot in time. In other words, GetInvocationList returns the list delegate objects that were present at the time the method was called. If you add a new delegate object to a multicast delegate, an array generated with an earlier call to GetInvocationList will not be in sync. You must call GetInvocationList again to create a new array that represents the updated list of delegate objects.


Wrap-up
This concludes my two-part discussion of programming with delegates. As you have seen, a delegate is a programmable binding mechanism for implementing a callback between a notification source and one or more handler methods. Delegates provide an attractive means for implementing callbacks because they combine the type safety and polymorphic capabilities of interfaces with the efficiency and flexibility of function pointers.
Understanding the fundamentals of programming with delegates is a prerequisite to becoming an advanced user of Visual Basic .NET. I say this for two reasons. First, event handling in the .NET Framework is entirely based on delegates. If you really want to make the most of an event-driven application framework such as Windows® Forms or ASP.NET, you'd better be prepared to drop down to a lower level and program in terms of delegates when it's required. Delegates also provide the primary means for executing a method on a secondary thread in an asynchronous fashion.
This month's Basic Instincts column builds upon my last two columns in which I talked about concepts and programming techniques associated with delegates. I will assume you have read the last two installments of this column and that you understand the role that delegates play within the Microsoft® .NET Framework. If you haven't read the last two columns, see Implementing Callback Notifications Using Delegates and Implementing Callbacks with a Multicast Delegate. You should also know how to design and write a simple application that uses multicast delegates to send callback notifications to a set of handler methods.
While you have probably been programming with events for years, migrating to the .NET Framework requires you to reexamine their inner workings because events in the .NET Framework are layered on top of delegates. The more you know about delegates, the more power you can harness when you program events. Your understanding of how events work at a lower level is critical when you start to work with one of the event-driven frameworks of the common language runtime (CLR) such as Windows® Forms or ASP.NET. My goal this month is to give you an understanding of how events work at a lower level.

What Exactly is an Event?
An event is just a formalized software pattern in which a notification source makes callbacks to one or more handler methods. Events are therefore similar to interfaces and delegates because they provide a means to design applications that use callback methods. However, events add a valuable degree of productivity because they are easier to use than interfaces or delegates. Events allow the compiler and the Visual Studio® .NET IDE to do much of the work for you behind the scenes.
A design that involves events is based on an event source and one or more event handlers. An event source can be either a class or an object. An event handler is a delegate object that's bound to a handler method. Figure 1 shows a high-level view of an event source wired up to its handler methods.

Figure 1 Event Source and Handlers
Every event is defined in terms of a particular delegate type. For each event defined by an event source, there is a private field that is based on the event's underlying delegate type. This field is used to track a multicast delegate object. An event source also provides a public registration method that allows you to register as many event handlers as you'd like.
When you create an event handler (a delegate object) and register it with an event source, the event source simply appends the new event handler to the end of the list. An event source can then use the private field to call Invoke on the multicast delegate which, in turn, will execute all the registered event handlers.
What's really nice about events is that much of the work to set them up is already done for you. As you will soon see, the Visual Basic® .NET compiler assists you by automatically adding a private delegate field and a public registration method whenever you define an event. You will also see that Visual Studio .NET provides even more assistance with a code generator that can automatically emit the skeleton definitions for your handler methods.


Programming with Events
Because events in .NET are built on top of delegates, their underlying plumbing details are very different from the way things used to work in previous versions of Visual Basic. However, the language designers of Visual Basic .NET did a good job in keeping the syntax for programming events consistent with earlier versions of Visual Basic. In many cases, programming events involves the same old familiar syntax you're used to using. For example, you will use keywords such as Event, RaiseEvent, and WithEvents, and they will behave almost identically to the way they have behaved in previous versions of Visual Basic.
Let's start by creating a simple callback design based on an event. First, I need to define an event within a class definition by using the Event keyword. Every event must be defined in terms of a specific delegate type. Here's an example of defining both a custom delegate type and a class that uses it to define an event:
Delegate Sub LargeWithdrawHandler(ByVal Amount As Decimal)

Class BankAccount
Public Event LargeWithdraw As LargeWithdrawHandler
'*** other members omitted
End Class
In this example, the LargeWithdraw event has been defined as an instance member. In this design, a BankAccount object will act as the event source. If you want a class instead of an object to act as an event source, you should define events as shared members using the Shared keyword.
When you program with events, it's important to acknowledge that the compiler is doing a good deal of extra work for you behind the scenes. For example, what do you think the compiler does when you compile the definition of the BankAccount class that I just showed you into an assembly? Figure 2 shows what the resulting class definition would look like when inspected with ILDasm.exe, the intermediate language disassembler. This view provides a revealing look at how much the Visual Basic .NET compiler is doing behind the scenes to assist you.

Figure 2 Class Definition in ILDasm
When you define an event, the compiler generates four members inside the class definition. The first member is a private field based on the delegate type. This field is used to track a reference to a delegate object. The compiler generates the name for this private field by taking the name of the event itself and adding the suffix "Event". This means that creating an event named LargeWithdraw results in the creation of a private field named LargeWithdrawEvent.
The compiler also generates two methods to assist with the registration and unregistration of delegate objects that are to serve as event handlers. These two methods are named using a standard naming convention. The method for registering an event handler is named after the event along with a prefix of "add_". The method for unregistering an event handler is named after the event along with a prefix of "remove_". Therefore, the two methods created for the LargeWithdraw event are named add_LargeWithdraw and remove_LargeWithdraw.
The Visual Basic .NET compiler generates an implementation for add_LargeWithdraw that accepts a delegate object as a parameter and adds it to the list of handlers by calling the Combine method of the Delegate class. The compiler generates an implementation for remove_LargeWithdraw that removes a handler method from the list by calling the Remove method in the Delegate class.
The fourth and final member that is added to the class definition is one that represents the event itself. You should be able to locate the event member named LargeWithdraw in Figure 2. It is the member with an upside-down triangle next to it. However, you should note that this event member isn't really a physical member like the other three. Instead, it's a metadata-only member.
This metadata-only event member is valuable because it can inform compilers and other development tools that the class supports the standard pattern for event registration in the .NET Framework. The event member also contains the names of the registration method and the unregistration method. This allows compilers for managed languages such as Visual Basic .NET and C# to discover the name of the registration method at compile time.
Visual Studio .NET is another good example of a development tool that looks for this metadata-only event member. When Visual Studio .NET sees that a class definition contains events, it automatically generates the skeleton definitions for handler methods as well as the code to register them as event handlers.
Before I move on to a discussion of raising events, I'd like to cover a restriction involved with creating a delegate type that's to be used for defining events. A delegate type used to define an event cannot have a return value. You must define the delegate type using the Sub keyword instead of the Function keyword, as shown here:
'*** can be used for events
Delegate Sub BaggageHandler()
Delegate Sub MailHandler(ItemID As Integer)

'*** cannot be used for events
Delegate Function QuoteOfTheDayHandler(Funny As Boolean) As String
There's a good reason for this restriction. It's far more difficult to work with return values in a case involving a multicast delegate that's bound to several handler methods. A call to Invoke on a multicast delegate returns the same value as the last handler method in the invocation list. However, capturing the return value of handler methods that appear earlier in the list isn't so straightforward. Eliminating the need to capture multiple return values simply makes events easier to use.


Raising an Event
Now let's modify the BankAccount class so that it's able to raise an event when a withdrawal is made for an amount that exceeds a $5000 threshold. The easiest way to fire the LargeWithdraw event is to use the RaiseEvent keyword within the implementation of a method, property, or constructor. This syntax is probably familiar because it's similar to what you have used in earlier versions of Visual Basic. Here's an example of firing the LargeWithdraw event from the Withdraw method:
Class BankAccount
Public Event LargeWithdraw As LargeWithdrawHandler
Sub Withdraw(ByVal Amount As Decimal)
'*** send notifications if required
If (Amount > 5000) Then
RaiseEvent LargeWithdraw(Amount)
End If
'*** perform withdrawal
End Sub
End Class
While the syntax remains the same from previous versions of Visual Basic, what happens when you raise an event is very different now. When you use the RaiseEvent keyword to fire an event, the Visual Basic .NET compiler generates the code required to execute each and every event handler. For example, what do you think happens when you compile the following code?
RaiseEvent LargeWithdraw(Amount)
The Visual Basic .NET compiler expands this expression to code that calls Invoke on the private field that holds the multicast delegate object. In other words, using the RaiseEvent keyword has the very same effect as writing the code in the following snippet:
If (Not LargeWithdrawEvent Is Nothing) Then
LargeWithdrawEvent.Invoke(Amount)
End If
Note that the code generated by the Visual Basic .NET compiler conducts a check to make sure that the LargeWithdrawEvent field contains a valid reference to an object. That's because the LargeWithdrawEvent field will have a value of Nothing until the first handler method is registered. Therefore, the generated code doesn't attempt to call Invoke unless at least one handler method is currently registered.
You should be able to make an observation about raising an event. It usually doesn't matter whether you use the RaiseEvent keyword or you program directly against the private LargeWithdrawEvent field that's automatically generated by the compiler. Both approaches produce equivalent code:
'*** this code
RaiseEvent LargeWithdraw(Amount)

'*** is the same as this code
If (Not LargeWithdrawEvent Is Nothing) Then
LargeWithdrawEvent.Invoke(Amount)
End If
In many cases, it's likely that you will prefer the syntax of the RaiseEvent keyword because it requires less typing and it results in code that is more concise. However, in certain situations where you need more control, it might make sense to explicitly program against the private LargeWithdrawEvent field. Let's look at an example of when this would be the case.
Imagine a scenario in which a BankAccount object has three event handlers that have been registered to receive notifications for the LargeWithdraw event. What would happen if you triggered the event using the RaiseEvent keyword and the second event handler in the invocation list threw an exception? The line of code containing the RaiseEvent statement would receive a runtime exception, but you would have no way to determine which event handler threw it. Furthermore, there would be no way to handle the exception thrown by the second event handler and to continue where the third event handler is executed as expected.
However, if you are willing to program in terms of the private LargeWithdrawEvent field, you can deal with an exception thrown by an event handler in a more graceful manner. Examine the code in Figure 3. As you can see, dropping down to a lower level and programming against the private delegate field provides an extra degree of control. You can gracefully handle an exception and then go on to execute event handlers that appear later in the list. This technique has obvious benefits over the RaiseEvent syntax in which an exception thrown by an event handler prevents the execution of any event handlers that appear later in the invocation list.


Creating and Registering an Event Handler
Now that you've seen how to define and raise an event, it's time to discuss how to create an event handler and register it with a given source. There are two different ways to accomplish this in Visual Basic .NET. The first technique is known as dynamic event binding and involves the use of the AddHandler keyword. The second technique is called static event binding and involves the use of the familiar Visual Basic keyword WithEvents. I plan to cover static event binding in a future column. So for now, let's examine how dynamic event binding works.
Remember that an event handler is a delegate object. Therefore, you create one by instantiating a delegate object from the delegate type on which the event is based. When you create this delegate object, you must bind it to a target handler method that you want to serve as an event handler.
Once you have created an event handler, you must register it with a specific event by calling the special registration method on the event source. Recall that the registration method for the LargeWithdraw event is named add_LargeWithdraw. When you call the add_LargeWithdraw method and pass a delegate object as a parameter, the event source adds the delegate object to the list of event handlers that are to receive event notifications.
What's confusing about event registration is that you never directly call a registration method such as add_LargeWithdraw. In fact, the Visual Basic .NET compiler will raise a compile-time error if you try to access an event registration method by name. Instead, you use an alternate syntax involving the AddHandler statement. When you use the AddHandler statement, the Visual Basic .NET compiler generates the code to call the event registration method for you.
Let's look at an example of wiring up a few event handlers using dynamic event registration. Imagine you have written the following set of shared methods in the AccountHandlers class:
Class AccountHandlers
Shared Sub LogWithdraw(ByVal Amount As Decimal)
'*** write withdrawal info to log file
End Sub

Shared Sub GetApproval(ByVal Amount As Decimal)
'*** block until manager approval
End Sub
End Class
What should you do if you'd like to employ these methods as event handlers for the LargeWithdraw event of the BankAccount class? Let's start by creating an event handler that's bound to the handler LogWithdraw. First, you must create the delegate object that's going to serve as an event handler:
Dim handler1 As LargeWithdrawHandler
handler1 = AddressOf AccountHandlers.LogWithdraw
Next, you must register this new delegate object with an event source using an AddHandler statement. When you register an event handler using the AddHandler statement, you are required to pass two parameters, like this:
AddHandler ,
The first parameter required by AddHandler is an expression that evaluates to an event of a class or object. The second parameter is a reference to the delegate object that is going to be wired up as an event handler. Here's an example of using an AddHandler statement to register an event handler with the LargeWithdraw event of a BankAccount object:
'*** create bank account object
Dim account1 As New BankAccount()

'*** create and register event handler
Dim handler1 As LargeWithdrawHandler
handler1 = AddressOf AccountHandlers.LogWithdraw
AddHandler account1.LargeWithdraw, handler1
When you use the AddHandler keyword to register an event handler for the LargeWithdraw event, the Visual Basic .NET compiler expands this code to call the registration method add_LargeWithdraw. Once the code containing the AddHandler statement has been executed, your event handler is in place and ready for notifications. Therefore, the LogWithdraw method will execute whenever the BankAccount object raises a LargeWithdraw event.
In the last example, I used a longer form of syntax to illustrate exactly what happens when you create and register an event handler. However, once you understand how things work, you might appreciate using a more concise syntax to accomplish the same goal, as shown here:
'*** create bank account object
Dim account1 As New BankAccount()

'*** register event handlers
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.GetApproval
Since the AddHandler statement expects a reference to a delegate object as the second parameter, you can use the shorthand syntax of the AddressOf operator followed by the name of the target handler method. When it sees this, the Visual Basic .NET compiler then generates the extra code to create the delegate object that is going to serve as the event handler.
The AddHandler statement of the Visual Basic .NET language is complemented by the RemoveHandler statement. RemoveHandler requires the same two parameters as AddHandler, yet it has the opposite effect. It removes the target handler method from the list of registered handlers by calling the remove_LargeWithdraw method supplied by the event source:
Dim account1 As New BankAccount()

'*** register event handler
AddHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw

'*** unregister event handler
RemoveHandler account1.LargeWithdraw, AddressOf AccountHandlers.LogWithdraw
Now you have seen all the steps required to implement a callback design using events. The code in Figure 4 shows a complete application in which two event handlers have been registered to receive callback notifications from the LargeWithdraw event of a BankAccount object.


Conclusion
While the motivation for using events and some of the syntax remains unchanged from previous versions of Visual Basic, you have to admit that things are rather different now. As you can see, you have far more control over how you respond to events than you've ever had before. This is especially true if you're willing to drop down and program in terms of delegates.
In the next installment of the Basic Instincts column I plan to continue this discussion of events. I'll show you how Visual Basic .NET supports static event binding through the familiar syntax of the WithEvents keyword, and I'll discuss the Handles clause. In order to really master events, you must be comfortable with both dynamic event registration and static event registration.

Monday, September 24, 2007

FAQ in Generics

1. Which Versions of the .NET Framework Support Generics?
Generics are only supported on version 2.0 and above of the Microsoft .NET framework, as well as version 2.0 of the compact framework.
2. Can I Use Generics in Web Services?
Unfortunately, no. Web services have to expose a WSDL-based contract. Such contracts are always limited by the expressiveness of the message format being used. For example, HTTP-GET based web services only support primitive types such as int or string, but not complex types like a DataSet. SOAP-based web services are more capable, but SOAP has no ability to represent generic type parameters. As a result, at present, you cannot define web services that rely on generic types. That said, you can define .NET web services that rely on closed constructed generic types, for example:
[C#]
public class MyWebService
{
[WebMethod]
public List GetCities()
{
List cities = new List();
cities.Add("New York");
cities.Add("San Francisco");
cities.Add("London"); return cities;
}
}
In the above example, List will be marshaled as an array of strings.
3. Can I Use Generics in Enterprise Services?
Unfortunately, no. All methods and interfaces on a ServicedComponent-derived class must be COM-visible. The COM type system is IDL, and IDL does not support type parameters.
4. Can I Use Generics in Indigo?
Unfortunately, no. SOAP has no ability to represent generic type parameters, and so all methods and interfaces on an indigo service contract or service class can only use primitive types such as integers or strings, or specific known types that provide a data contract. As a result, at present, you cannot define Indigo services that rely on generic types, that is, services that leave it up to the service consumer to specify the types to use when invoking the service.
5. Can I Use Generics in .NET Remoting?
Yes. You can expose generic types as remote objects, for example:
[C#]
public class MyRemoteClass : MarshalByRefObject {...}
Type serverType = typeof(MyRemoteClass);
RemotingConfiguration.RegisterWellKnownServiceType(serverType, "Some URI", WellKnownObjectMode.SingleCall);
Note that the specific type arguments used must be a marshalable type, that is, either serializable or derived from MarshalByRefObject. Consequently, a generic remote type will typically place a derivation constraint from MarshalByRefObject on its generic type parameters when expecting reference type parameters:
[C#]
public class MyRemoteClass : MarshalByRefObject where T : MarshalByRefObject {...}
To administratively register a generic type, provide the type arguments in double square brackets.
For example, to register the class MyRemoteClass with an integer, you should write:

The double square brackets is required in case you need to specify multiple type arguments, in which case, each type arguments would be encased in a separate pair of brackets, separated by a comma. For example, to register the class MyRemoteClass with an integer and a string, you would write:

Creating a new instance of generic remote objects is done just as with non-generic remote objects.
6. Can I Use Visual Studio 2003 or the .NET Framework 1.1 to Create Generics?
Unfortunately no. Generics are only supported on version 2.0 and above of the Microsoft .NET framework. Code that relies on generics must run on version 2.0 of the CLR. Because of the way the CLR version unification works, a run-time process can only load a single version of the CLR. Consequently, a process that loaded version 1.1 of the CLR cannot use generic types. If you must use generic types from .NET 1.1, you can use the following work-around: First, wrap the generic types with object-based types (at the expense of course of the benefits of using generics). Next, load the wrapper classes in a separate process which loads version 2.0 of the CLR, and provide remote access to the wrapper classes to legacy clients in process that use version 1.1 of the CLR. For remote communication you can use any number of cross-process communication mechanisms, such as Remoting, Enterprise Services, sockets, etc.
6. What Environment Do I Need to Use Generics?
To deploy and run code that uses generics you need version 2.0 or higher of the .NET runtime.
7. Can I Use Generics on the Compact Framework?
Yes. The .NET Compact Framework version 2.0 supports generics. Like most other things with the .NET Compact Framework, the generics support is very close but not exactly the same as the normal .NET Framework, due to performance and schedule constrains. You can use generics with both C# and Visual Basic for the compact framework. The compact framework does apply certain limitations on generics, the notable ones are:
· The compact framework does not verify constraints are runtime, only at compile time.
· You can only have up to 8 generic type parameters per generic type.
· You cannot use reflection on unbounded generic types.
8. Which .NET Languages Support Generics and How?
Both C# 2.0 and Visual Basic 2005 support defining and consuming generics. Visual C++ 2005 also supports generics in addition to classic C++ templates. Visual J# 2005 supports consuming generic types but not defining them. At present, it is not known of other vendors besides Microsoft that added generics support for their languages.
9. Where Does the .NET Framework Itself Use Generics?
Version 2.0 of the .NET Framework makes use of generics in three main areas: The System namespace added a large set of static generic methods to the Array type. These methods automate and streamline common manipulations of and interactions with arrays. The System namespace also defined a number of generic utility delegates, which are used by the Array type and the List class, but can be used freely in other contexts as well. In addition, System provides support for nullable types. The System namespace defines the IComparable interface and the EventHandler delegate, both generic reincarnations of their non-generic predecessors. The System namespace also defines the IEquatable interface, used to check for equality of two values. The System namespace defines the ArraySegment used to allocate a strongly typed portion of an array.
The System.Collections.Generic namespace defines generic collection interfaces, collections and iterator classes, similar to the old, non generic ones available in the System.Collections namespace. The System.Collections.Generic namespace also defines a few generic helper classes and structures.
The System.ComponentModel namespace defines the class BindingList. A binding list is used very similar to a mere generic list, except it can fire events notifying interested parties about changes to its state.
The System.Collections.ObjectModel namespace defines a few types such as Collection that can be used as base types for custom collections.
Finally, all the types that supported IComparable in .NET 1.1 support IComparable and IEquatable in .NET 2.0. This enables you to use common types for keys, such as int, string, Version, Guid, DateTime, and so on.
10. What Are the Generic Collection Classes?
The System.Collections.Generic namespace contains the majority of the new generic collections. These collections are by and large the generic reincarnation of the collections available in the System.Collections namespace. For example, there is a generic Stack and a generic Queue classes. The collections in System.Collections.Generic are used in much the same way as their predecessors. In addition, some of the collections where renamed in the process. The Dictionary data structure is equivalent to the non-generic HashTable, and the class List is analogous to the non-generic ArrayList. System.Collections.Generic also defines new types that have no equivalent in System.Collections, such as LinkedList and KeyValuePair. In addition, The System.Collections.Generic namespace defines generic interfaces such as ICollection and IList. To support generic-based iterators, System.Collections.Generic defines the IEnumerable and IEnumerator interfaces, and these interfaces are supported by all the generic collections. It is important to note that the generic collections can be used by clients that do not rely on generics, because all the generic collections also support the non-generic collection and iteration interfaces (IList, ICollection, IEnumerable). For example, here is the definition of the List class:
[C#]
public class List : IList,IList {...}
The System.ComponentModel namespace defines the type BindingList.
[C#]
public class BindingList : Collection, IBindingList,ICancelAddNew,IRaiseItemChangedEvents
{
public event ListChangedEventHandler ListChanged;
public event AddingNewEventHandler AddingNew;
public BindingList();
public BindingList(List list);
public T AddNew();
//More members
}
BindingList is used similarly to a generic list, except it can fire events notifying interested parties about changes to its state, so you can bind it to user interface controls such as the ListBox. You can use BindingList directly or you can wrap it around an existing List.
The System.Collections.ObjectModel namespace defines the types Collection, KeyedCollection, ReadOnlyCollection, and ReadOnlyCollection provided as base types for custom providers. Interestingly enough, none of the .NET-provided generic collections actually use these base collections.
Finally, the System namespace defines the ArraySegment helper structure, which can be used to obtain a generic-based segment of a provided array.
The following table lists the generic collections and their supporting types, including mapping the generic collections to those of System.Collections or other namespaces when applicable.





Type
Namespace
Non-Generic Equivalent
Comment
ArraySegment
System
-
Used to obtain a generic-based segment of a provided array
BindingList
System.ComponentModel
-
Linked list that fires state changes events
Collection
System.Collections.ObjectModel
Collection
Non abstract base class for other collections
Comparer
System.Collections.Generic
Comparer
Implements IComparer and IComparer
Dictionary
System.Collections.Generic
HashTable
Implements IDictionary
EqualityComparer
System.Collections.Generic
-
Abstract class implementing IEqualityComparer
ICollection
System.Collections.Generic
ICollection
Count and synchronization for a collection
IComparer
System.Collections.Generic
IComparer
Compares two specified values
IDictionary
System.Collections.Generic
IDictionary
Interface for a collection of key/value pairs
IEnumerable
System.Collections.Generic
IEnumerable
Returns an IEnumerator object
IEnumerator
System.Collections.Generic
IEnumerator
Iterating over a collection
IEqualityComparer
System.Collections.Generic
IEqualityComparer
(.NET 2.0 only)
Equates two specified values.
IList
System.Collections.Generic
IList
Implemented by list collections or access by index
KeyedCollection
System.Collections.ObjectModel
-
Base class for keyed collections
KeyValuePair
System.Collections.Generic
-
Container for key/value pair
LinkedList
System.Collections.Generic
-
A true linked list
LinkedListNode
System.Collections.Generic
-
Used by LinkedList, but can be used by custom lists as well.
List
System.Collections.Generic
ArrayList
Impalements IList over an array
Queue
System.Collections.Generic
Queue
A queue
ReadOnlyCollection
System.Collections.ObjectModel
ReadOnlyCollectionBase
Base class for read-only collections
SortedDictionary
System.Collections.Generic
SortedList
Implements IDictionary over a sorted collection
SortedList
System.Collections.Generic
SortedList
A sorted linked list over an array and a hash table.
Stack
System.Collections.Generic
Stack
A stack

11. What Are the Generic Delegates?
The System namespace defines five new generic delegates. The first is EventHandler defined as:
[C#]
public delegate void EventHandler(object sender,E e) where E : EventArgs
EventHandler can be used wherever an event handling method expects an object and an EventArgs-derived class as parameters. Obviously, that is the case wherever the non-generic EventHandler was used in .NET 1.1:
[C#]
public delegate void EventHandler(object sender, EventArgs e)
But in addition, EventHandler can be employed instead of all the other delegates that used EventArgs-derive class, such as MouseEventHandler:
[C#]
public class MouseEventArgs : EventArgs {...}
public delegate void MouseEventHandler(object sender,MouseEventArgs e);
void OnMyMouseEvent(object sender,MouseEventArgs e) {...}
//Instead of:
MouseEventHandler handler += OnMyMouseEvent;
//You can write:
EventHandler handler += OnMyMouseEvent;
The other four generic delegates found in the System namespace are designed to be used in conjunction with the static generic methods of Array or the List type, but you can easily use them in other contexts:
[C#]
public delegate void Action(T t); public delegate int Comparison(T x, T y); public delegate U Converter(T from); public delegate bool Predicate(T t);
generic
public delegate void Action(T t);
generic
public delegate int Comparison(T x, T y);
generic
public delegate U Converter(T from);
generic
public delegate bool Predicate(T t);
For example, here is using the Action delegate to trace every value in a given array:
[C#]
string[] cities = {"New York","San Francisico","London"};
Action trace = delegate(string text) { Trace.WriteLine(text); }; Array.ForEach(cities,trace);
12. What Are the Generic Methods of System.Array?
The System.Array type is extended with many generic static methods. The generic static methods are designed to automate and streamline common tasks of working with arrays, such as iterating over the array and performing an action on each element, scanning the array looking for a value that matches a certain criteria (a predicate), converting and sorting the array, and so on. Below is a partial listing of these static methods:
[C#]
public abstract class Array
{
//Partial listing of the static methods:
public static ReadOnlyCollection AsReadOnly(T[] array);
public static int BinarySearch(T[] array,T value);
public static int BinarySearch(T[] array,T value, IComparer
comparer);
public static U[] ConvertAll(T[] array, Converter converter); public static bool Exists(T[] array,Predicate match);
public static T Find(T[] array,Predicate match);
public static T[] FindAll(T[] array,Predicate match);
public static int FindIndex(T[] array,Predicate match);
public static void ForEach(T[] array,Action action);
public static int IndexOf(T[] array,T value);
public static void Sort(T[] array,IComparer comparer);
public static void Sort(T[] array,Comparison comparison);
}
Most of these static generic methods work with the four generic delegates defined in the System namespace:
[C#]
public delegate void Action(T t);
public delegate int Comparison(T x, T y);
public delegate U Converter(T from);
public delegate bool Predicate(T t);
For example, suppose the array roles contains all the roles a user plays at your application, and you would like to find out if the user is a member or a specified role.
[C#]
bool IsInRole(string role)
{
string[] roles = GetRoles();
Predicate exists = delegate(string roleToMatch)
{
return roleToMatch == role;
};
return Array.Exists(roles,exists);
}
string[] GetRoles() {...}
The Array.Exists() method defined as:
[C#]
public static bool Exists(T[] array,Predicate match);
takes a single type parameter (the type of the array). The compiler can infer the type automatically, so there is no need to specify that. The second parameter is a generic delegate of type Predicate(), which returns a Boolean value. The Array.Exists() method iterates over the array, and invokes the predicate delegate on each item in the array. If the predicate returns true, it stops the iteration and returns true. If all the items in the array return false from invoking the predicate on them, Array.Exists() returns false. In C#, you can initialize the predicate using an anonymous method, and have Array.Exists() invoke that method on every item in the array until the predicate is satisfied or there are no more items.
To demystify how those various methods work, here is how Array.Exist() could be implemented:
[C#]
public abstract class Array
{
public static bool Exists(T[] array,Predicate match)
{
if(array == null)
{
throw new ArgumentNullException("array");
}
if(match == null)
{
throw new ArgumentNullException("match");
}
foreach(T t in array)
{
if(match(t))
{ return true; }
}
return false;
} //Rest of the methods }
13. What Are the Generic Methods of List?
Besides implementing IList, the List type contains many generic helper methods. These methods are designed to automate and streamline common tasks of working with the list, such as iterating over the list and performing a task on each element, scanning the list looking for a value that matches a certain criteria (a predicate), or just searching for a particular value, converting and sorting the list, and so on. Below is a partial listing of these generic methods:
[C#]
public class List : IList,
{
//Partial listing of the generic helper methods:
public List ConvertAll(Converter converter);
public bool Exists(Predicate match);
public T Find(Predicate match);
public List FindAll(Predicate match);
public int FindIndex(Predicate match);
public T FindLast(Predicate match);
public void ForEach(Action action);
public int LastIndexOf(T item);
public void Sort(Comparison comparison);
public T[] ToArray(); //More members
}
Most of these helper generic methods works with the four generic delegates defined in the System namespace:
[C#]
public delegate void Action(T t);
public delegate int Comparison(T x, T y);
public delegate U Converter(T from);
public delegate bool Predicate(T t);
The List helper methods are used much the same way as the generic static methods of System.Array. For example, the following code initializes a list with all the numbers from 1 to 20. Then, using the Action delegate, the code traces these numbers using the List.ForEach() method. Using the Predicate delegate, the code finds all the prime numbers in the list by calling the List.FindAll() method, which returns another list of the same type. Finally, the prime numbers are traced, using the same Action delegate.
[C#]
int[] numbers = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
List list = new List(numbers);
Action trace = delegate(int number)
{
Trace.WriteLine(number);
};
Predicate isPrime = delegate(int number)
{
switch(number)
{
case 1:case 2:case 3:case 5:case 7:
case 11:case 13:case 17:case 19:
return true;
default:
return false;
}
};
list.ForEach(trace);
List primes = list.FindAll(isPrime);
primes.ForEach(trace);
14. What Are Nullable Types?
Unlike reference types, you cannot assign a null into a value type. This is often a problem when interacting with code that interprets a null as having no value, rather than no-reference. The canonical example is database null values in columns that have representation as types such as int or DateTime. To address that, the System namespace provides the structure Nullable defined as:
[C#]
public interface INullableValue
{
bool HasValue{get;}
object Value{get;}
}
[Serializable] public struct Nullable : INullableValue,IEquatable nullable,... where T : struct
{
public Nullable(T value);
public bool HasValue{get;}
public T Value{get;}
public T GetValueOrDefault();
public T GetValueOrDefault(T defaultValue);
public bool Equals(Nullable other);
public static implicit operator Nullable(T value);
public static explicit operator T(Nullable value);
//More members
}
Because the Nullable struct uses a generic type parameter, you can use it to wrap a value type, and assign null into it:
[C#]
Nullable number = 123;
Debug.Assert(number.HasValue);
number = null;
Debug.Assert(number.HasValue == false);
Debug.Assert(number.Equals(null));
Once a null is assigned to a nullable type, you can still access it to verify if it has a value, via the HasValue property, or just equate it to null.
In C# and Visual Basic, you can even use the underlying value type's operators on a nullable type:
[C#]
Nullable number = 0; number++;
The reason this is possible is because the compiler is capable of verifying that the underlying type supported the operator, and applying it on the value stored in the structure. This is called lifted operators.
The Nullable struct also provides conversion operators, so you can convert a nullable type to and from a real value type:
[C#]
Nullable nullableNumber = 123;
int number = (int)nullableNumber;
Debug.Assert(number == 123);
number = 456;
nullableNumber = number;
Debug.Assert(nullableNumber.Equals(456));
Note that using Nullable on Nullable is disallowed, and the compiler will issue an error:
[C#]
//This will not compile: Nullable nullable number = 123;
You can use the overloaded methods GetValueOrDefault() of Nullable to defensively obtain either the value stored in the nullable type or it its default, if it does contain a null:
[C#]
Nullable time = null;
DateTime value = time.GetValueOrDefault();
Debug.Assert(value.ToString() == "1/1/0001 12:00:00 AM");
The System namespace also defines the static helper class Nullable and the helper class NullableConverter, but those are not needed usually.
The C# 2.0 compiler supports shorthand for Nullable. You can use the ? modifier on value types to actually construct a Nullable around it:
int? number = 123;
Debug.Assert(number.HasValue);
number = null;
Debug.Assert(number.HasValue == false);
Note that the type declared by the ? modifier is identical to that created using Nullable directly:
Debug.Assert(typeof(int?) == typeof(Nullable));
As with using Nullable directly, the compiler supports lifted operators. Whenever you combine nullable types using operators, if any one of them is null, then the resulting expression will be null too:
int? number1 = 123;
int? number2 = null;
int? sum = number1 + number2;
Debug.Assert(sum == null);
Using the ? modifier is the common way of declaring and using nullable variables in C#. You can even pass nullable types as type arguments for generic types:
IList list = new List();
list.Add(3);
list.Add(null);
C# 2.0 also provides the null coalescing operator via the ?? operator.
c = a ?? b;
The result of applying the ?? operator on two operands returns the left hand side operand (a) if it is not null, and the right operand (b)otherwise. While b can of course be null too, you typically use the ?? operator to supply a default value in case a is null.
15. How Do I Reflect Generic Types?
Like most other things done with reflection, you use the class Type. Type can represent generic types with specific type arguments (called bounded types), or unspecified (unbounded) types.
[C#]
Both typeof and GetType() can operate on type parameters:
public class MyClass
{
public void SomeMethod(T t)
{
Type type = typeof(T);
Debug.Assert(type == t.GetType());
}
}
In addition the typeof operator can operate on unbound generic types (generic types that do not have yet specific type arguments). For example:
public class MyClass
{}
Type unboundedType = typeof(MyClass<>);
Trace.WriteLine(unboundedType.ToString());
//Writes: MyClass`1[T]
The number 1 being traced is the number of generic type parameters of the generic type used. Note the use of the empty <>. To operate on an unbound generic type with multiple type parameters, use a , in the <>:
public class LinkedList
{...}
Type unboundedList = typeof(LinkedList<,>);
Trace.WriteLine(unboundedList.ToString());
//Writes: LinkedList`2[K,T]
[Visual Basic]
Both GetType() and Object.GetType() can operate on type parameters:
Public Class SomeClass(Of T) Public Sub SomeMethod(ByVal t As T) Dim theType As Type = GetType(T) Debug.Assert((theType Is t.GetType)) End Sub End Class
To support generics, Type has special methods and properties designed to provide reflection information about the generic aspects of the type:
[C#]
public abstract class Type : //Base types
{
public virtual bool ContainsGenericParameters{get;}
public virtual GenericParameterAttributes GenericParameterAttributes{get;}
public virtual int GenericParameterPosition{get;}
public virtual bool IsGenericType{get;}
public virtual bool IsGenericParameter{get;}
public virtual bool IsGenericTypeDefinition{get;}
public virtual Type[] GetGenericArguments();
public virtual Type[] GetGenericParameterConstraints();
public virtual Type GetGenericTypeDefinition();
public virtual Type MakeGenericType(params Type[] typeArguments);
//Rest of the members
}
The most useful of these new members are the IsGenericType property, the GetGenericArguments() and GetGenericTypeDefinition() methods. As its name indicates, IsGenericType is set to true if the type represented by the Type object uses generic type parameters. GetGenericArguments() returns an array of types corresponding to the type arguments used. GetGenericTypeDefinition() returns a Type representing the generic form of the underlying type. The following example demonstrates using these generic-handling Type members to obtain generic reflection information on a generic linked list.
[C#]
public class LinkedList
{...}
LinkedList list = new LinkedList();
Type boundedType = list.GetType();
Trace.WriteLine(boundedType.ToString());
//Writes:
LinkedList`2[System.Int32,System.String] Debug.Assert(boundedType.IsGenericType);
Type[] parameters = boundedType.GetGenericArguments();
Debug.Assert(parameters.Length == 2);
Debug.Assert(parameters[0] == typeof(int));
Debug.Assert(parameters[1] == typeof(string));
Type unboundedType = boundedType.GetGenericTypeDefinition(); Trace.WriteLine(unboundedType.ToString());
//Writes: LinkedList`2[K,T]

Wednesday, September 19, 2007

What;s New in .Net 3.0 ?

A glance at .NET Framework 3.0Introduction:In the programming field, .NET is the most successful development platform..Net Framework 2.0 is enough to satisfy for most of us. .NET Framework 3.0 came with many new and useable features. With .NET Framework 3.0, developers feel more easy when develops. In the new version of .NET, there is nothing new with CLR (Common Language runtime) but it introduces four new technologies. Are we not apprehensive about accepting anything newer, especially if that is going to deprecate the existing one? The latest versions of .NET are .NET Framework 3.0. Programming with .NET Framework 3.0 become more advance. It is built with all the advantage of .NET framework 2.0, and is all set to bring in a paradigm shift in the way we write our applications today. When we go to develop any application then the main goal we set is, to create the Best application in least amount of time. The .NET Framework 3.0 will still ship with Windows Vista, and will be available down-level for Windows XP and Windows Server 2003 as planned.This newly released framework was earlier named as WinFx! .NET Framework 3.0 , compromise of familiar .NET Framework2.0 components (ASP.NET, ADO.NET, Window Forms etc).There are four new technologies in .NET Framework 3.0. These technologies are added to face the new challenge of software development. These new complementary technologies are added to address some of the most arduous challenges of contemporary software development.The New in .NET Framework 3.0Here .NET Framework 3.0 is same like as .NET Framework 2.0, but with some new technology and feature. The entire features are same in new framework, which was in .NET Framework 2.0.The .NET 3.0 introducing four new foundation technologies:Windows Presentation Foundation (WPF)Windows Communication Foundation (WCF)Windows Workflow Foundation (WWF)Windows Card Space (WCS)While the .NET Framework 2.0 class library is partially superseded by the new components (WF, WCF, and WPF) added in version 3.0, many portions of the original class library are still crucial to developers. The technologies of version 2.0 (ASP.NET, WinForms, ADO.NET, XML etc.) largely remain the elementary part of the new release; however, the developer of .NET Framework 3.0, mostly use WPF over windows Forms.Figure 1: NET Framework 3.0Windows Workflow Foundation (WF): Windows Workflow Foundation (WWF) is a Microsoft technology for defining, executing, and managing workflows. Workflow as it name implies. It shows the flow of work; mean how the work is going, how activities are performing. WF provides such a common workflow technology for Windows. If we have to make workflow enabled application on windows then we use Windows Workflow Foundation.System.Workflow is the namespace of Windows Workflow Foundation in Microsoft .NET Framework version 3.0. Windows Workflow Foundation provides full support for Visual Basic .NET and C#, debugging, a graphical workflow designer and the ability to develop our workflow completely in code. A workflow is a set of activities stored as a model that describe a real world process. Each Activity can be represented as a class. By using this we can reuse that activity easily. With WF, we can understand with our flow of operation. We can easily understand with our all activity.Windows Presentation Foundation (WPF): The Windows Presentation Foundation (WPF), also named Avalon, is the graphical subsystem feature of the .NET Framework 3.0. WPF is a consistent programming model for building solutions, and enables the use of richer controls, design, and development in Windows programs. In most windows application user interface play an important role .A developer needs to use Windows Forms to build a Windows GUI, or HTML/ASPX/Applets/JavaScript etc. Developer's job become tough here when he go to, building a coherent user interface for different kinds of clients using diverse technologies isn't a simple job. WPF provide consistent platform for these entire user interface aspects to solve the problem. WPF support video, animation, 2/3D graphics, and various kinds of documents.Windows Communication Foundation (WCF): WCF means programmers can communicate between each other either they are on same computer or in networking .Windows Communication Foundation is a communications infrastructure built around the Web services architecture. When the application becomes built then most of the application need to communication between each other. This was a big problem in last few years, so all vendors becomes agreed to support SOAP based web services, which make interoperability between application, either they are from same platforms or different platforms. The WCF programming model unifies web services, .NET Remoting, distributed transactions, and message queues into a single service-oriented programming model for distributed computing. However, instead of requiring developers to use a different technology with a different application programming interface for each kind of communication, WCF provides a common approach and API. WCF provides strong support for interoperable communication through SOAP. Windows CardSpace (WCS):Windows CardSpace (InfoCard) is a Digital Identity to online services. Digital Identity means how user will electronically represent them. Like as a debit/credit card each card has digital identity and password. If any user go to use the site on internet then he enter their username and password, for identity, but this is not secure. To reduce these types of problems WCS works. WCS (originally called Info Card) helps people keep track of their digital identities as distinct information cards. If a Web site accepts WCS logins, users attempting to log in to that site will see a WCS selection. By choosing a card, users also choose a digital identity that will be used to access this site. CardSpace and the new supporting technologies will change how you authenticate into an application, whether it sits on the Web, your phone, or your desktop.