I have a method with a generic parameter:
internal void DoSomething<T>(T workWithThis)
{
}
I now want to constrain this method to only accept parameters which inherit one of a few interfaces I'd like to specify. However I have not yet found a way to it. What I'd like looks like this:
internal void DoSomething<T>(T workWithThis) where T : ISomething | ISomethingElse
{
}
Obviously this is not working, so I tried it with a static method to check the Type of T:
public static bool CheckType(Type t)
{
return */check here*/
}
internal void DoSomething<T>(T workWithThis) where T : CheckType(typeof(T))
{
}
Obviously this is not going to work either. The question is why? Why is the compiler preventing me from doing that, based on my understanding there is no reason for it not to work
Why is the compiler preventing me from doing that, based on my understanding there is no reason for it not to work
The compiler is preventing you from doing it because you're trying to do something which isn't supported by C# as a language. The syntax you're trying to use does not comply with the productions in section 10.1.5 of the C# spec.
C# as a language simply does not support the scenario you require.
Now as for why the language doesn't allow this sort of flexibility - that comes down to the normal balancing act of:
Oh, and of course this isn't just C# - the CLR would have to support such a restriction as well, and it would at least encourage other CLR languages to understand it too.
I suggest you solve this by having two separate methods. Note that they can't just be overloads of generic methods, as overloads cannot differ only by generic type constraints. If you don't mind about boxing for value types implementing the interface, you could overload with:
internal void DoSomething(ISomething something)
{
}
internal void DoSomething(ISomethingElse somethingElse)
{
}
... although then if you pass in a value where the expression is a type implementing both interfaces, you'll end up with overload ambiguity.
Alternatively, just give the two methods different names.
See more on this question at Stackoverflow