I tested this code and got that it doesn't compiles.
interface IE<T>
{
}
class A<T> : IE<T>
{
public static void F<TU>() where TU : IE<T>
{
}
static void Foo()
{
F<A<int>>();
}
}
It fails even if I add public static void F<TU>() where TU : A<int>, IE<T>
.
afaik it's valid according to C# specs. If I remove contraint where TU : IE<T>
but in this case it couldn't affect, because A<int>
is subtype of IE<T>
.
And it's also funny because resharper suggest to add IE<T>
interface to A
why this code isn't valid?
No, it's not valid. The constraint of
where TU : IE<T>
refers to the current T
, i.e. the one for the type on which you're calling this method.
Consider a call of:
A<string>.Foo();
That's trying to pass A<int>
as a type argument for TU
, but the constraint means that there must be a reference conversion from TU
to IE<string>
, because T
is string
.
There's no conversion from A<int>
to IE<string>
, hence it's broken. Basically your expectation of "A<int>
is subtype of IE<T>
" isn't true for all T
.
Now you could change it to:
public static void F<TU, TT>() where TU : IE<TT>
{
}
static void Foo()
{
F<A<int>, int>();
}
That's now valid, because it doesn't involve T
at all.
See more on this question at Stackoverflow