可能重复:
铸造列表<gt;的派生类列表<gt;基本类
这个标题可能讲不通。查看代码:
class Person {}
class Manager : Person {}
class PaymentCalculator<T> where T : Person
{
public double Calculate(T person)
{
return 0; // calculate and return
}
}
class Calculators : List<PaymentCalculator<Person>>
{
public Calculators()
{
this.Add(new PaymentCalculator<Person>());
this.Add(new PaymentCalculator<Manager>()); // this doesn't work
PassCalculator(new PaymentCalculator<Person>());
PassCalculator(new PaymentCalculator<Manager>()); // this doesn't work
}
public void PassCalculator(PaymentCalculator<Person> x)
{ }
}
代码中标记为"这不起作用"的两行代码无法编译。
我可以解决这个问题,但我的意图似乎没有错。或者,是吗?
即使Manager
从Person
继承,PaymentCalculator<Manager>
也不会从PaymentCalculator<Person>
继承。如果PaymentCalculator<T>
是反变量的,它会起作用,但类在中不能是反变量。NET(只有接口和委托可以是相反的)。
你的问题的一个可能的解决方案是声明一个反变体接口,如下所示:
interface IPaymentCalculator<in T> // "in" means contravariant
{
double Calculate(T person);
}
使PaymentCalculator<T>
实现IPaymentCalculator<T>
接口:
class PaymentCalculator<T> : IPaymentCalculator<T> where T : Person
{
public double Calculate(T person)
{
return 0; // calculate and return
}
}
并使Calculators
类继承自List<IPaymentCalculator<Person>>
class Calculators : List<IPaymentCalculator<Person>>
有了这些更改,它应该如您所期望的那样工作。
没错。"默认情况下"new MyClass<Derived>()
不可分配给new MyClass<Base>()
。但是你可以使用接口的协变来完成这个技巧:
class Person { }
class Manager : Person { }
interface IPaymentCalculator<out T> where T : Person
{
}
class PaymentCalculator<T> : IPaymentCalculator<T> where T : Person
{
public double Calculate(T person)
{
return 0; // calculate and return
}
}
class Calculators : List<IPaymentCalculator<Person>>
{
public Calculators()
{
this.Add(new PaymentCalculator<Person>());
this.Add(new PaymentCalculator<Manager>()); // this doesn't work
PassCalculator(new PaymentCalculator<Person>());
PassCalculator(new PaymentCalculator<Manager>()); // this doesn't work
}
public void PassCalculator(IPaymentCalculator<Person> x)
{ }
}
这将编译并工作。