Generics usage 1/2

Classes that take type parameters have significantly more functionality, this is the idea behind generics, they have been added form C# 2.0

Defining a Simple Generic Class

//ex1

public class MyDataStruct<T>
{
	T[] _items = null;

	public void Add(T item)
	{
		//...
	}
	public T Remove()
	{
		//...
		return default(T);
	}
}

// using the MyDataStruc<T>
MyDataStruct<string> mdsString = new MyDataStruct<string> ();
mdsString.Add ("ABC");

MyDataStruct<int> mdsInt = new MyDataStruct<int> ();
mdsString.Add (123);

The advantage are in summary:

  1.  Generics facilitate a strongly typed programming model, because when you instantiate the class you need to define the type of T parameter, co the compiler knows how to handle it
  2. Compile-time type checking reduces the likelihood of InvalidCastException type errors at runtime, in fact using a collection of Array, for example, to support general params you need to assure the params passed are of the correct type at runtime
  3. Using value types with generic class members no longer causes a cast to object; they no longer require a boxing operation, this happened using Array where you need to use cast to convert the array content
  4. Generics in C# reduce code bloat, you don’t need to create and derive specialized classes to handle special types ex MyDataStructInt, MyDataStructString etc… derived from :MyDataStruct, plus the necessary overloading and inevitable code duplication

Interface and Generics

You can define Interface that accepets Generics Types as well

Interface ICombineTwo<T>
{
	T CombineTwo (T t1, T t2);
}

public class MyDataStruct<T> : ICombineTwo<T>
{

	public T CombineTwo (T t1, T t2)
	{
		// ...
		return default(T);
	}
}

MyDataStruct<string> mdsString = new MyDataStruct<string> ();
mdsString.CombineTwo("ABC","DEF");
// Fail: mdsString.CombineTwo("ABC",123);

Arity

The number of type parameters, it’s called the arity, uniquely distinguishes the class

//ex3
public class MyDataStruct<T> {
	//...
}
public class MyDataStruct<T1,T2> {
	//...
}

//ex3
MyDataStruct<string> mdsString = new MyDataStruct<string> ();
MyDataStruct<string,char> mdsStringChar = new MyDataStruct<string,char> ();

Constraints

With Generics you can define constraints on type parameters accepted, the definition uses a where and the condition definition, let’s see some usage

Interface Constraints

To ask for minimum ‘can do’ behaviour though the interface

//ex4
public class MyDataStruct<T>
	where T: System.IComparable<T>
{
	public void SortItems()
	{
		//... here use sort and it need T to be Comparable
	}
}

public class NotCompatableFoo
{
}

//ex4
MyDataStruct<string> mdsString = new MyDataStruct<string> ();
mdsString.SortItems();
//Fail:	MyDataStruct<NotCompatableFoo> mdsNotCompatableFoo = new MyDataStruct<NotCompatableFoo> ();

Base Class Constraints

Or to limit the constructed type to a particular class derivation


//ex5
public class MyDataStruct<T> where T : MyClass
{
	public void SortItems ()
	{
		//... here use sort and it need T to be Comparable
	}
}

public class MyClass
{
}
public class MyDerivedClass : MyClass
{
}

//ex5
MyDataStruct<MyClass> mdsMyClass = new MyDataStruct<MyClass> ();
MyDataStruct<MyDerivedClass> mdsMyDerivedClass = new MyDataStruct<MyDerivedClass> ();
//Fail	MyDataStruct<string> mdsString = new MyDataStruct<string> ();

N> Another valuable generic constraint is the ability to restrict type parameters to a value type or a reference type, you simply use the keyword struct or class.

Next post on Generic Methos, Covariance and Contravariance …

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s