I want to implement a generic method on a generic class which would allow to cast safely, see example:
public class Foo<T> : IEnumerable<T>
{
...
public IEnumerable<R> SafeCast<R>()
where T : R
{
return this.Select(item => (R)item);
}
}
However, the compiler tells me that Foo<T>.SafeCast<R>() does not define parameter 'T'. I understand this message that I cannot specify a constraint on T in the method since it is not defined in the method. But how can I specify an inverse constraint?
C# does not have that kind of constraint. A constraint has to be of the form “R must be convertible to X”; we do not support constraints of the form “R must be convertible from X”.
Which is unfortunate, since it makes certain scenarios involving contravariant conversions easier.
Scala permits such a constraint, incidentally.
Interestingly enough, you can do what you want with an extension method, but you then have to be redundant when you call it:
Now you can say:
In C# 4 your code will be largely unnecessary;
IEnumerable<T>is safely covariant in T in C# 4 if T is a reference type.