【问题标题】:Use derived class type as parameter of generic action of base class使用派生类类型作为基类通用动作的参数
【发布时间】:2016-08-19 10:05:53
【问题描述】:

我想通过委托来操作一个实例,这是类本身的一个属性。委托的参数应该始终是实例本身(即使在派生类中!)。

见下面的代码。我知道代码没有编译,因为我必须将 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; }
}

编辑: 更改代码!

我的问题是,是否有一个很好的解决方案可以仅在基类中处理所有这些问题,但在操作中我想使用派生类而不进行强制转换。

【问题讨论】:

  • 哪里出了问题?如果这是问题,您可以使用所有继承的类覆盖的virtual 方法。
  • Car.VehicleManipulator 操作为空,您从未分配过它,将其设为虚拟,编译器将在派生类中寻找实现
  • @A.T.相反, that 属性被赋值,但该方法使用 基类的 属性。这不是关于空值,而是关于继承
  • @Snowcrack - 仅删除派生中的属性就不会进行强制转换。这首先是继承的想法——你在那个基类上添加了更多。为什么要在派生中使用另一个具有相同类型和名称的属性?
  • 您在派生类中重新引入了VehicleManipulator,这是故意的吗?你知道这样做的效果吗?

标签: c# generics inheritance action


【解决方案1】:

你很接近。你得到NullReferenceException 这行car.ManipulateVehicle(); 的原因是VehicleManipulator 操作为空。

如您所见,基类的VehicleManipulator 属性为空。

现在,如果您在分配操作时失败的那条线上方,它怎么可能为空?所以问题是,在您的派生类 car 中,您有一个名为 VehicleManipulator 的新 不同 属性,它隐藏了基类。因此,当您分配 car.VehicleManipulator 时,您实际上是在派生类中分配属性,而不是在基类中。

派生类中删除它会起作用。

如果出于我还无法理解的原因,您确实希望将属性保留在派生类中,那么在进行分配时,您可以指定要分配给基类,如下所示:

【讨论】:

  • @Snowcrack - 这是否阐明了发生的情况并帮助您解决问题?
【解决方案2】:

如果您想避免强制转换,请将 Vehicle 设为通用,如:

class Vehicle<T> where T : Vehicle {
     Action<T> ManipulateVehicle { get; set; }
}

class Car : Vehicle<Car> {
    int SomeInt { get; set; }
}

这看起来有点奇怪,但这意味着如果你有一个汽车实例,那么机械手就可以在汽车上工作,如果你有卡车,它就可以在卡车上工作,等等。车辆可能应该是抽象的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 2017-06-21
    • 1970-01-01
    • 2014-08-05
    • 2012-04-21
    相关资源
    最近更新 更多