5

是否可以在 C# 中编译以下代码?我确实在 Java 中进行了类似的编译。

public interface IInterface
{
    ...
}

public class Class1 : IInterface
{
    ...
}

public abstract class Base<T> where T : IInterface
{
    ...
}

public class Class2<T> : Base<T> where T : IInterface
{
    ...
}

.
.
.

public SomeMethod()
{
    List<Base<IInterface>> list = new List<Base<IInterface>>();
    Class2<Class1> item = new Class2<Class1>();
    list.Add(item); // Compile error here
}
4

3 回答 3

7

不,这在 C# 中是不合法的。当使用引用类型构造泛型接口和泛型委托时,C# 4 及更高版本支持协变和逆变。例如,IEnumerable<T>是协变的,所以你可以说:

List<Giraffe> giraffes = new List<Giraffe>() { ... };
IEnumerable<Animal> animals = giraffes;

但不是

List<Animal> animals = giraffes;

因为动物列表可以插入老虎,但长颈鹿列表不能。

对 C# 中的协变和逆变进行 Web 搜索,您会发现很多关于它的文章。

于 2013-09-29T14:54:19.763 回答
3

看起来 .NET Framework 4.0 支持泛型接口和委托中的协变。所以,我碰巧通过添加一个通用接口来编译代码。

public interface IInterface
{
    ...
}

public class Class1 : IInterface
{
    ...
}

public interface IBase<out T> where T: IInterface
{
    // Need to add out keyword for covariance.
}

public class Base<T> : IBase<T> where T : IInterface
{
    ...
}

public class Class2<T> : Base<T> where T : IInterface
{
    ...
}

.
.
.

public SomeMethod()
{
    List<IBase<IInterface>> list = new List<IBase<IInterface>>();
    Class2<Class1> item = new Class2<Class1>();
    list.Add(item); // No compile time error here.
}
于 2013-09-30T12:32:30.033 回答
0

你不能像这样使用泛型。列表类型是 IInterface 但你尝试将 Class1 类型添加到列表中。它应该如下..

        List<Base<Class1>> list = new List<Base<Class1>>();
        Class2<Class1> item = new Class2<Class1>();
        list.Add(item); 
于 2013-09-29T11:06:47.300 回答