Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use System.ValueType as a generics constraint?

Tags:

c#

generics

  • Why can't I use a constraint of where T : System.ValueType?
  • Why does Microsoft prevent this type from being a constraint?

Example:

Why can't I do the following?

// Defined in a .Net class public void bar<T>(T a) where T : ValueType {...}  // Defined in my class public void foo<T>(T a) where T : ValueType  { bar<T>(a); } 

What is the difference in using struct over ValueType?

// Defined in my class public void foo<T>(T a) where T : struct  { bar<T>(a); } 
like image 223
zfedoran Avatar asked Dec 06 '09 07:12

zfedoran


People also ask

How do you add a generic constraint?

You can specify one or more constraints on the generic type using the where clause after the generic type name. The following example demonstrates a generic class with a constraint to reference types when instantiating the generic class.

Can a generic class have multiple constraints?

Multiple interface constraints can be specified. The constraining interface can also be generic.

How do you indicate that a class has a generic type parameter?

A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.


2 Answers

There are two differences between using

where T : struct 

and

where T : ValueType 
  • the latter would allow T to be ValueType itself, which is a reference type.
  • the latter would also allow T to be a nullable value type

The first of these differences is almost never what you want. The second could occasionally be useful; Nullable<T> is slightly odd in that it satisfies neither the where T : struct nor where T : class constraint.

More useful would be the constraint

where T : struct, System.Enum 

which is prohibited by C# for no good reason that I can tell. See my blog post and the Unconstrained Melody project for more on this.

like image 53
Jon Skeet Avatar answered Oct 08 '22 21:10

Jon Skeet


ValueType is not the base class of value types, it is simply a container for the value when it is boxed. Since it is a container class and not in any sort of hierarchy for the actual types you're wanting to use, it is not useful as a generic constraint.

like image 33
Rex M Avatar answered Oct 08 '22 20:10

Rex M