Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Covariance/contravariance: how to make the following code compile

UPDATE: The following code only makes sense in C#4.0 (Visual Studio 2010)

It seems like I am having some misunderstanding of covariance/contravariance thing. Can anybody tell me why the following code doesn't compile?

public class TestOne<TBase>
{
    public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values)
        where TDerived: TBase
    {
        return values;
    }
}

while this one compiles: (!!!)

public interface IBase
{
}
public interface IDerived: IBase
{
}
public class TestTwo
{
    public IEnumerable<IBase> Method(IEnumerable<IDerived> values)
    {
        return values;
    }
}
like image 890
Trident D'Gao Avatar asked Feb 20 '12 15:02

Trident D'Gao


1 Answers

Covariance only applies to reference types (for the type arguments), so you have to add a class constraint:

public IEnumerable<TBase> Method<TDerived>(IEnumerable<TDerived> values)
    where TDerived : class, TBase
{
    return values;
}

This will prevent you from trying to convert, say, an IEnumerable<int> into an IEnumerable<object>, which is invalid.

like image 90
Jon Skeet Avatar answered Nov 09 '22 13:11

Jon Skeet