Generics Cheat Sheet

A cheat sheet for Generics in C#

All source code can be found on GitHub here.

This post is part of my cheat sheet series.

My How To in Generics can be found here while some code examples can be found in my post here.

// **** WHY GENERICS ****
// Type Safe: Prevent having to cast between obect and a type when retrieving data from objects such as classes

// Faster: Value types which are placed into classes which are designed to be used on multiple types. No need to box/unbox value types.
// Allocating an object on the heap from the stack and vice versa is slow

// When you have multiple method overloads which have the same functionality for multiple types

// If you find yourself restrcting access to an Interface or a base class then you should ask yourself if generics is really required here

// **** CONSTRAINTS ****
// Constrains provide a way to limit which types can be used
// In most cases no constraintss should be used
where T: struct 	// Value Type; System.ValeValue is found as an ancestor
where T: class 		// Reference type; System.ValeValue is not found as an ancestor (any class, interface, delegate or array type)
where T: new() 		// Provides a parameterless constructor.
where T:  	// Has an ancestory
where T:  	// Implements an interface
where T: U 		// One provided type is an ancestor of another.

// Examples
class Test<T, U> where U : struct where T : Base, new() {}
class List{ void Add<span style="text-decoration: underline;">(List<span style="text-decoration: underline;"> items) where U : T {}
class SampleClass<T, U, V> where T : V {}
void SomeFunction(T aValue) where T : V {}

// **** EQUALITY  ****
// Can not use != & == operators as we can not gurantee that concrete type will implement these
// Can compare to null though for value types will always return false.

// **** DEFAULT VALUE ****
return default(T); // returns the default value of the type; 0 for int etc.

// **** CASTING ****
// Can cast to and from System.Object and explcitly convert to any interfaces.
// Implicit cast can be to object or to constraint-specified types only.
// Implicit casting is type safe as incompatibility is discovered at compile-time.
// Explicit cast can be to interface only

// Consider
class MyClass where T : BaseClass, ISomeInterface {}

ISomeInterface obj1 = t;
BaseClass      obj2 = t;
object         obj3 = t;

// Explicit
ISomeInterface obj1 = (ISomeInterface)t;	//Compiles
SomeClass      obj2 = (SomeClass)t;     	//Does not compile

// Explcity achieved via temp object; is dangerous. better to use is or as operator
object temp = t;
MyOtherClass obj = (MyOtherClass)temp;

// Can Cast
bool IsInterface = typeof(ISomeInterface).IsAssignableFrom(typeof(T));
if(t is int)
if(t is LinkedList<int,string>)

// AS Cast; like a cast but returns null on failure
t as IDisposable
expression is type ? (type)expression : (type)null // equivalent to as
using(t as IDisposable)

// **** ATTRIBUTES ****
// These can not be used however you can check owning functions

// **** TYPE ANALYSYS ****

// TypeCode Enum
TypeCode typeCode = Type.GetTypeCode( testObject.GetType() );

// IsType

// Nullable Types

// Parse & Try Parse
Integer.TryParse( "1", out aValue)

// Change Type: Returns an object of the specified type and whose value is equivalent to the specified object.
int i = (int)Convert.ChangeType(-2.345, typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("12/12/98", typeof(DateTime));

// TypeDescriptor Converter
public static T GetTfromString(string mystring)
   var foo = TypeDescriptor.GetConverter(typeof(T));
   return (T)(foo.ConvertFromInvariantString(mystring));

Leave a Reply

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

You are commenting using your 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