我一遍又一遍地看到这个错误:
无法从
Item<Foo>
转换为Item<IFoo>
。
这显然是无稽之谈; Item<Foo>
类型的对象静态保证能够完成Item<IFoo>
可以做的所有事情(可能还有更多),那么为什么编译器拒绝接受我的完全有效的代码?
我有一个接受Item<IFoo>
作为参数的方法。出于某种原因,即使Item<Foo>
实现Foo
,它也拒绝接受IFoo
作为输入。这毫无意义。我可以通过Foo
代替IFoo
,但我无法通过Item<Foo>
代替Item<IFoo>
。为什么呢?
public class Item<T>
{
public readonly int ID;
public readonly T Data;
...
}
public void ProcessItem(Item<IFoo> item)
{
Console.WriteLine(item.ID);
}
ProcessItem(new Item<Foo>());
答案 0 :(得分:3)
C#中的类是不变的,因此根据您的要求,您必须创建一个接口和实现:
public interface IItem<out T> { ... }
public class Item<T> : IItem<T> { ... }
IItem<IFoo> item = new Item<Foo>();
请注意,将Class<Subtype>
分配给Class<Basetype>
并不一定安全。一个常见的例子是List<T>
:
List<object> l = new List<string>(); //won't compile
l.Add(3);
C#仅允许接口和委托上的方差注释,并且只有在安全的情况下才允许这样做。