Miguel Moura
Miguel Moura

Reputation: 39514

Restrict generic T to specific types

I have the following method:

public static IResult<T, String> Validate<T>(this T value) {
} // Validate

How can I restrict T to be Int16, Int32, Int64, Double and String?

Upvotes: 15

Views: 15406

Answers (3)

Jaanus Varus
Jaanus Varus

Reputation: 3573

Constraining a generic to a set of specific types is not available. But other types of constraints are. The closest you can get with generics to what you want to achieve is to add the following constraints:

public static IResult<T, String> Validate<T>(this T value) 
    where T : IConvertible, IComparable, IComparable<T>, IEquatable<T>
{
    // Validate
}

All the primitive types implement these interfaces. To further restrict, the only option is to check the type at runtime and throw an exception if it doesn't match:

Type type = typeof(T);
if (type != typeof(Int16) &&
    type != typeof(Int32) &&
    type != typeof(Int64) &&
    type != typeof(Double) &&
    type != typeof(String))
{
    throw new ArgumentException();
}

This isn't the nicest solution, but at least it will give you a bit of compile time and runtime safety.

Upvotes: 6

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

You can't restrict generics in that way, you can only choose a single class as a constraint. You must either make 5 overloads or find a interface all 5 of those things share and use that. Which option you choose will depend on what Validate doe.

Here is how you would do the overloads.

public static IResult<Int16, String> Validate<T>(this Int16 value) {
} // Validate

public static IResult<Int32, String> Validate<T>(this Int32 value) {
} // Validate

public static IResult<Int64, String> Validate<T>(this Int64 value) {
} // Validate

public static IResult<double, String> Validate<T>(this double value) {
} // Validate

public static IResult<String, String> Validate<T>(this String value) {
} // Validate

Here is by using a common interface, all of the members you list Implement IConvertible so you could restrict by that, however this will allow any IConvertible not just the 5 you listed.

public static IResult<T, String> Validate<T>(this T value) where IConvertible {
} // Validate

Upvotes: 7

Sjoerd222888
Sjoerd222888

Reputation: 3486

You can only do this:

public static IResult<T, String> Validate<T>(this T value) where T: int
{
    //validate
} 

Only classes and interfaces can be used as constraint.

Upvotes: 12

Related Questions