![](/img/trans.png)
[英]Can not use second level derived class as parameter of generic base class type
[英]Use derived class type as parameter of generic action of base class
我想通过一个委托来操作一个实例,它是类本身的一个属性。 委托的参数应该始终是实例本身(即使在派生类中!)。
请参阅下面的代码。 我知道代码没有编译,因为我必须将 car1 强制转换为 car,我正在寻找一种无需强制转换的解决方案。
代码
static void Main(string[] args)
{
var car = new Car();
car.VehicleManipulator = car1 => car1.SomeInt++;
car.ManipulateVehicle();
Console.WriteLine("end");
Console.ReadLine();
}
internal class Vehicle
{
public Action<Vehicle> VehicleManipulator { get; set; }
public void ManipulateVehicle()
{
this.VehicleManipulator(this);
}
}
internal class Car : Vehicle
{
public int SomeInt { get; set; }
}
编辑:更改代码!
我的问题是,是否有一个很好的解决方案可以仅在基类中处理所有这些,但在操作中我想使用派生类而不进行强制转换。
你很近。 这条线car.ManipulateVehicle();
得到NullReferenceException
的原因car.ManipulateVehicle();
是因为VehicleManipulator
动作为空。
如您所见,基类的VehicleManipulator
属性为 null。
现在,如果您在分配操作时失败了,那么它怎么可能为空? 所以问题是在您的派生类 car 中,您有一个名为VehicleManipulator
的新的不同属性,它隐藏了基本属性。 因此,当您分配car.VehicleManipulator
您实际上是在派生类中而不是在基类中分配属性。
从派生类中删除它会起作用。
如果出于我尚不明白的原因,您确实希望将属性保留在派生类中,那么在进行分配时,您可以指定要分配给基类,如下所示:
如果您想避免强制转换,请使 Vehicle 通用,例如:
class Vehicle<T> where T : Vehicle {
Action<T> ManipulateVehicle { get; set; }
}
class Car : Vehicle<Car> {
int SomeInt { get; set; }
}
这看起来有点奇怪,但这意味着如果你有一个汽车实例,操纵器可以在汽车上工作,如果你有一辆卡车,它可以在卡车上工作等等。 车辆可能应该是抽象的。
只需从Car类中删除以下代码行:
public Action<Car> VehicleManipulator { get; set; }
ManipulateVehicle是基类的方法,并且在调用时具有基类(未派生)的VehicleManipulator属性的功能。
将VehicleManipulator
属性添加到派生类将隐藏基础属性,并在分配属性时-基础属性的默认值为null
因此为NullReferenceException
我还建议您将关键字abstract
添加到Vehicle
的签名中,因为它是纯抽象的。 一个人不能只创建没有类型等的车辆,只能创建汽车,卡车,摩托车等
因此,工作代码可以是这样的:
abstract internal class Vehicle
{
public virtual Action<Vehicle> VehicleManipulator { get; set; }
public void ManipulateVehicle()
{
this.VehicleManipulator(this);
}
}
internal class Car : Vehicle
{
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.