I'm having a hard time understanding why it would be beneficial to do something like this: (Sample is a class)
static void PrintResults<T>(T result) where T : Sample
Wouldn't it be better to to just pass Sample into the method?
static void PrintResults (Sample result)
Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.
Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.
C# allows you to use constraints to restrict client code to specify certain types while instantiating generic types. It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the specified constraints.
I recommend avoiding generic types where non-generic syntax works, such as the example you gave. However, there are other useful cases.
For example, specifying the return type generically:
static T Create<T>() where T: Sample, new()
{
return new T();
}
// Calling code
Sample sample = Create<Sample>();
instead of
static object Create()
{
return new Sample();
}
// Calling code
Sample sample = (Sample) Create();
You can also use templates to place multiple restrictions on a type. For example:
static T Create<T>() where T: IMyInterface, new()
{
return new T();
}
interface IMyInterface {}
class MyClass : IMyInterface { }
// Calling code.
MyClass myClass = Create<MyClass>();
This allows the generic creation of a new type that implements a specific interface and has a generic constructor. Also:
static void DoSomething<T>(T t) where T: IMyInterface1, IMyInterface2
{
t.MethodOnIMyInterface1();
t.MethodOnIMyInterface2();
}
interface IMyInterface1
{
void MethodOnIMyInterface1();
}
interface IMyInterface2
{
void MethodOnIMyInterface2();
}
class MyClass: IMyInterface1, IMyInterface2
{
// Method implementations omitted for clarity
}
// Calling code
MyClass myclass'
DoSomething(myclass); // Note that the compiler infers the type of T.
Where you can require multiple interfaces on a single parameter without (1) creating a new type that implements all these interfaces and (2) requiring parameters to be of that type.
As @dcastro points out in his/her answer, generic types can also tell the compiler to require types are the same. For example:
static void DoSomething<T>(T t1, T t2) where T: MyType
{
// ...
}
class MyType {}
class MyType1: MyType {}
class MyType2: MyType {}
// Calling code
MyType1 myType1;
MyType2 myType2;
DoSomething<MyType>(myType1, myType2);
Where the compiler requires that t1 and t2 are the same type but can be any type that inherits MyType
. This is useful in automated unit testing frameworks, such as NUnit or MSTest, for generic equality and comparison checks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With