我想通过委托来操作实例,委托是类本身的属性。委托的参数应该始终是实例本身(即使在派生类中!)。
见下面的代码。我知道代码没有编译,因为我必须将car1转换为car 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; }
}
编辑: 改变了代码!
我的问题是,是否有一个很好的解决方案来处理基类中的所有这些,但在操作中我想使用派生类而不进行转换。
答案 0 :(得分:4)
你很亲密。您为此行NullReferenceException
获得car.ManipulateVehicle();
的原因是因为VehicleManipulator
操作为空。
正如您所看到的,基类的VehicleManipulator
属性为null。
现在如果你在失败的线上方分配动作,它怎么能为空呢?所以问题在于,在你的派生类car中,你有一个新的不同的属性,其名称为VehicleManipulator
,隐藏了基本属性。因此,当您分配car.VehicleManipulator
时,实际上是在派生类中而不是在基类中分配属性。
从派生类中删除它会起作用。
如果由于某个我无法理解的原因,您确实希望将该属性保留在派生类中,那么在进行分配时,您可以指定要分配给基类,如下所示:
答案 1 :(得分:2)
如果您想避免施放,请将“车辆”设为通用,如:
class Vehicle<T> where T : Vehicle {
Action<T> ManipulateVehicle { get; set; }
}
class Car : Vehicle<Car> {
int SomeInt { get; set; }
}
它看起来有点奇怪,但这意味着如果你有一个汽车的实例,机械手在汽车上工作,如果你有一辆卡车,它可以在卡车上工作等等。车辆应该是抽象的。
答案 2 :(得分:0)
只需从Car class中删除这行代码:
public Action<Car> VehicleManipulator { get; set; }
ManipulateVehicle是基类的方法,在调用时,它使用base(非派生)类的VehicleManipulator属性。
将VehicleManipulator
属性添加到派生类隐藏基本属性以及何时分配 - base属性的默认值为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
{
}