繁体   English   中英

使用派生类类型作为基类泛型操作的参数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM