Wednesday, 15 March 2006
 Monday, 13 March 2006

Demo on Command Pattern and Enterprise Library 2.0

During the Developers and IT Pro days 2006, Jelle Druyts and I gave a session on best practices for Application Development.  I have not had the chance to upload the full presentation and the demo's, but would already like to share the second demo with you, which is on the Command Pattern and Enterprise Library.  There are parts of the Command Pattern code that is not fully documented or could be improved (especially the way we handle asynchronous invocation), but we had a deadline that could not be moved!  If you like the Command Pattern implementation and would like to see it improved, do not hesitate to contact me.

 

You can download the finished version of the demo : Finished.zip (1,39 MB) and the references that are required to run the demo References.zip (729,52 KB)

 

Enjoy!


.NET 2.0
03/13/2006 23:54:59 UTC  #  Comments [2] 
 Wednesday, 18 May 2005

Generics Part I - Introduction

Generics or parametric polymorphism allow classes, structs, interfaces, delegates and methods to be parameterized by the type of data they utilize.  It has the following advantages over dynamic approaches:

  • stability

stronger compile time type checking

  • expressivity

invariants expressed in type signatures

  • clarity

fewer explicit conversions between data types

  • efficiency

reduce the need for run-time type checks and boxing operations

Object-based generic design pattern

Without generics, programmers often use the Object-based generic design pattern.  This is a complicated term for something as simple as storing data of any type as an instance of the type Object.  The following List class stores its data in an Object array and the methods Add and the indexer use the Object type to accept and return data:

public class List

{

      private object[] _items;

           

      public object this [int index] {...}

      public void Add(object value) {...}

}

The Object-based generic design applied in the above sample provides the List class with parameter type flexibility.  It is possible to add a value of any type to the List but this solution still has following drawbacks:

  • When the value passed to the Add method is a value type, it is automatically boxed. 
  • When the value returned by the indexer is a value type it must be unboxed with an explicit type cast.  Boxing and unboxing operations add a performance overhead because they involve memory allocations and runtime type checks.
  • When the value returned by the indexer is a reference type, an explicit cast to the appropriate type has to be performed.  This has a performance penalty for the required runtime checking and is quite tedious to write.
  • There is no compile time type checking.  This may cause that problems do not become apparent until the code is executed and an InvalidCastException is thrown.

As you may or may not suspect by now, generics allow us to overcome the abovementioned drawbacks.

 

What are Generics?

Generics provide class creators the tools to create types that have type parameters.  Rather than forcing conversions to and from Object, instances of generic types accept the types for which they were created and allow us to store the data without any conversions.  The passed type parameter is a placeholder until an actual type is specified during utilization.  The following example uses the parameter TypeOfList as the type for:

  • the internal _items array
  • the parameter type for the Add method
  • the return type for the indexer.

public class List <TypeOfList>

{

      private TypeOfList[] _items;

                 

      public TypeOfList this [int index] {...}

      public void Add(TypeOfList value){...}

}

 

When you want use the generic class List, you must specify the actual type for the type substitute TypeOfList:

List<int> list = new List<int>();

 

In the constructed type List<int>, every occurrence of the type substitute TypeOfList is replaced with the type argument int.  A constructed type is a generic type that is named with its type parameters.  When an instance of the type List<int> is used in code, the following applies:

  • The native storage for the _items array is int[], this provides an improved storage efficiency compared to the non-generic List. 
  • Generics provide strong typing. This means that at compile time and at runtime it will be verified that only int values or values that can be implicitly cast to an int are used as parameter. 
  • The indexer will return an int value, this eliminates the explicit cast to an int when it is retrieved and thus eliminates the unbox operation.

Generic type declarations may have any number of type parameters.  The following example illustrates its use:

public class Dictionary <TypeOfKey, TypeOfValue>

{

      public void Add(TypeOfKey key, TypeOfValue value){...}

public TypeOfValue this [TypeOfKey key] {...}

}

 

Constraints

So far the benefits of generics only apply to constructed types.  But when you are coding a generic class, you will find that the type of the parameters is still no more specific than the Object type.  It’s currently impossible to call any type specific method on the parameter values.  To provide us with this information C# permits an optional list of constraints to be supplied for each type parameter.  A type parameter constraint allows you to specify a requirement that a type must fulfill.  Constraints are declared using the word where, followed by:

  • The name of the parameter;
  • a class type (optionally);
  • interface types (optionally);
  • the new() constraint, that allows you to specify the requirement for a public parameterless constructor (optionally).

public class Dictionary <TypeOfKey, TypeOfValue>

where TypeOfKey: IComparable<TypeOfKey>

      where TypeOfValue: IPersistable, new ()

{

public void Add(TypeOfKey key, TypeOfValue value) {…}

}

 

Given the abovementioned declaration, where the type argument for TypeOfKey is constrained to implement IComparable the following applies:

  • the compiler guarantees that any type argument supplied for TypeOfKey implements IComparable;
  • All members of IComparable are directly available on values of the type parameter TypeOfKey.

public void Add (TypeOfKey key, TypeOfValue value)

{

if (key.CompareTo(value) < 0 {…}

}

 

Generic Methods

When you only need a type parameter in a particular method, you will probably want to use a generic method.  A generic method has one or more type parameters specified between < and > delimiters after the method name.  The type parameters can be used within the:

  • parameter list
  • return type
  • body of the method. 

A generic AddDictionary will probably look like this:

public void AddDictionary (Dictionary<TypeOfKey, TypeOfValue> dictionary) {…}

 

Good news?

Yes, there are least 4 more posts to come on generics: 

  • Generics Part II – Generic Declarations
  • Generics Part III - Advanced Generics;
  • Generics Part IV - Generic Performance and Guidelines;
  • Generics Part V - Generic Implementation or what I make of it.

.NET 2.0
05/18/2005 21:37:04 UTC  #  Comments [2]