Since IEnumerable
has a covariant parameter in C# 4.0 I am confused how it is behaving in the following code.
public class Test
{
IEnumerable<IFoo> foos;
public void DoTestOne<H>(IEnumerable<H> bars) where H : IFoo
{
foos = bars;
}
public void DoTestTwo(IEnumerable<IBar> bars)
{
foos = bars;
}
}
public interface IFoo
{
}
public interface IBar : IFoo
{
}
So basically the DoTestOne
method doesn't compile while DoTestTwo
does. In addition to why it doesn't work, if anyone knows how I can achieve the effect of DoTestOne
(assigning an IEnumberable<H> where H : IFoo
to an IEnumberable<IFoo>
) I would appreciate the help.
If you know that H will be a class, this does work:
public void DoTestOne<H>(IEnumerable<H> bars) where H : class, IFoo
{
foos = bars;
}
The issue here is that if H is a value type, the covariance is not exactly what you'd expect, as IEnumerable<MyStruct>
actually returns the value types whereas IEnumerable<IFoo>
has to return boxed instances. You can use an explicit Cast<IFoo>
to get around this, if necessary.
You simply need a cast to IEnumerable<IFoo>
in there:
public void DoTestOne<H>(IEnumerable<H> bars) where H : IFoo
{
foos = (IEnumerable<IFoo>)bars;
}
Edit courtesy of Dan Bryant: using foos = bars.Cast<IFoo>()
instead of above circumvents the InvalidCastException when H
is a struct
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With