我有以下类定义
public class AbstractIem<T> where T : SomeObject
{
public abstract T Item { get; }
}
public class ConcreteItem1 : AbstractItem<ClassExtendingSomeObject>
{
public override ClassExtendingSomeObject Item { get; }
}
public class ConcreteItem2 : AbstractItem<AnotherClassExtendingSomeObject>
{
public override ClassExtendingSomeObject Item { get; }
}
我遇到问题的地方是当我想动态分配一个AbstractItem<SomeObject>
的对象时,
AbstractItem<SomeObject> myItem;
switch (someIntValue)
{
case 1:
myItem = new ConcreteItem1();
break;
case 2:
myItem = new ConcreteItem2();
break;
}
尝试设置myItem
时出现以下错误:
不能将类型"ConcreteItem1"隐式转换为"抽象项">
我认为这应该有效,因为每个ConcreteItem
类都扩展到AbstractItem<SomeObject>
SomeObject
是具体类型。
您尝试执行的操作称为方差,在 C# 中,它只能在接口上实现。因此,要使其正常工作,您必须将AbstractItem<T>
更改为接口并将T
标记为协变。
public interface IItem<out T> where T : SomeObject
{
T Item { get; }
}
public class ConcreteItem1 : IItem<ClassExtendingSomeObject>
{
public ClassExtendingSomeObject Item { get; }
}
public class ConcreteItem2 : IItem<AnotherClassExtendingSomeObject>
{
public AnotherClassExtendingSomeObject Item { get; }
}
注意out
IItem
声明中T
前面添加了关键字。
通过该设置,以下代码按预期工作:
IItem<SomeObject> myItem;
switch (someIntValue)
{
case 1:
myItem = new ConcreteItem1();
break;
case 2:
myItem = new ConcreteItem2();
break;
}
有关 .NET 中的协方差和逆变的详细信息,请参阅 learn.microsoft.com 中的泛型中的协方差和逆变。