1884 Contributors: 33 Monday, March 13, 2017
Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Rip Tutorial:
Roadmap: roadmap
Download eBook


Download c# eBook


  • public void SomeMethod <T> () { }
  • public void SomeMethod<T, V>() { }
  • public T SomeMethod<T>(IEnumerable<T> sequence) { ... }
  • public void SomeMethod<T>() where T : new() { }
  • public void SomeMethod<T, V>() where T : new() where V : struct { }
  • public void SomeMethod<T>() where T: IDisposable { }
  • public void SomeMethod<T>() where T: Foo { }
  • public class MyClass<T> { public T Data {get; set; } }


T, VType placeholders for generic declarations


Generics in C# are supported all the way down to the runtime: generic types built with C# will have their generic semantics preserved even after compiled to CIL.

This effectively means that, in C#, it is possible to reflect on generic types and see them as they were declared or check if an object is an instance of a generic type, for example. This is in contrast with type erasure, where generic type information is removed during compilation. It is also in contrast with the template approach to generics, where multiple concrete generic types become multiple non-generic types at runtime, and any metadata required to further instantiate the original generic type definitions is lost.

Be careful, however, when reflecting on generic types: generic types' names will be altered on compilation, substituting the angled brackets and the type parameters' names by a backtick followed by the number of generic type parameters. Thus, a Dictionary<TKey, Tvalue> will be translated to Dictionary`2.

Related Examples