Question

Is it possible to constrain a genericised method to accept only specific types of struct?

This is OK I believe:

string Add<T>(object value, T expiration) where T : struct; 

but this isn't it appears:

string Add<T>(object value, T expiration) where T : Struct1, Struct2; 

Note: the structs I wish to constrain it to are DateTime or TimeSpan and hence I have no control over them.

Thanks

Was it helpful?

Solution

No, as a struct is sealed (you can't create a subclass of a ValueType).

Instead, consider having your structs implement an interface, then use that as a constraint, like so:

string Add<T>(object value, T expiration) where T : struct, IMyInterface

OTHER TIPS

The purpose of generics is to make methods and types that are generic, hence the name. If you only have two possible type arguments, then just write two methods.

Remember also, C# generics are not C++ templates. When you call a method on a type parameter, say, that method call will be the exact same method call for every construction of the type parameter. It's generic. It's not a template where the compiler compiles the code two, three, a thousand times, one for each type argument, and works out afresh for each one what the method call is.

So even if you could restrict your type argument to two types, what good would that do you? All you could call on them was the methods they had in common via their base class, Object. In which case, you've got a generic method that works on all objects, so why restrict it to two types?

I expect an overload is your best option here:

string Add(object value, MyStruct1 expiration) {...}
string Add(object value, MyStruct2 expiration) {...}

This is even more appropriate since you can't subclass a struct, thus the only viable T in your example would be MyStruct1 and MyStruct2 - may as well have specific methods, then.

Re restricting generics to multiple cited types; not really - and even if there were, the name "Add" suggests you'd want to use operator support, which also isn't in C# (3.0).

However, in C# 4.0, dynamic might be an option here - this acts as an optimised form of duck-typing; you wouldn't get compiler support (validation etc), but it should work. You would cast to dynamic inside the method:

string Add<T>(object value, T expiration) where T : struct {
    dynamic valueDyn = value;
    valueDyn += expiration; // or similar
    // more code
}

Another option (in .NET 3.5) is to use the Operator support in MiscUtil, using Operator.Add or Operator.AddAlternative.

I think both are not OK, a struct is not a valid constraint. A type used as a constraint must be interface, non sealed or a type parameter

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top