Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Type Parameter constraints in C# .NET

Consider the following Generic class:

public class Custom<T> where T : string
{
}

This produces the following error:

'string' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter.

Is there another way to constrain which types my generic class can use?

Also, can I constrain to multiple types?

E.G.

T can only be string, int or byte

like image 379
Matthew Layton Avatar asked Nov 12 '12 13:11

Matthew Layton


2 Answers

public class Custom<T> where T : string

is not allowed, because the only T that meets that is: string (string is sealed) - making it rather pointless as a generic.

Also, can I constrain to multiple types?

no - unless you do that at runtime via reflection rather than in a constraint (the static constructor is one way to do that - throwing an exception if used incorrectly)

T can only be string, int or byte

You might use something like IEquatable<T>, but that doesn't restrict it as much as you would like, so ultimately: no.

Something you could do is access it via an overloaded factory:

public abstract class Custom
{
    public static Custom Create(int value)
    { return new CustomImpl<int>(value); }
    public static Custom Create(byte value)
    { return new CustomImpl<byte>(value); }
    public static Custom Create(string value)
    { return new CustomImpl<string>(value); }
    private class CustomImpl<T> : Custom
    {
        public CustomImpl(T val) { /*...*/ }
    }
}
like image 97
Marc Gravell Avatar answered Sep 21 '22 14:09

Marc Gravell


From my experience I would say that I understand why you would like to have, string and int ... because of a generic base class having ID of type string or int

But it is for sure, that this is not possible. As this msdn description says: http://msdn.microsoft.com/en-us/library/d5x73970%28v=vs.80%29.aspx

We can have a constraing class (reference object like string) or struct (ValueType like int) So mixing string and int won't be possible

NOTE: the error for string make sense, because string is sealed, so it do not have to be as generic - string ID is what we need

like image 26
Radim Köhler Avatar answered Sep 22 '22 14:09

Radim Köhler