可能重复:
Casting List<> of Derived class to List<> of base class
标题可能没有多大意义。见代码:
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)
{ }
}
代码中的两行标记为&#34;这不起作用&#34;不会编译。
我可以解决这个问题,但看起来我的意图并不错。或者,是吗?
答案 0 :(得分:1)
这是对的。 “默认情况下,”new MyClass<Derived>()
无法分配给new MyClass<Base>()
。但你可以使用co-variance of interfaces:
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)
{ }
}
这将编译和工作。
答案 1 :(得分:1)
即使Manager
继承自Person
,PaymentCalculator<Manager>
也不会继承PaymentCalculator<Person>
。如果PaymentCalculator<T>
是contravariant,它将起作用,但.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>>
通过这些更改,它应该按预期工作。