Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用派生类类型作为基类的泛型操作的参数_C#_Generics_Inheritance_Action - Fatal编程技术网

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

C# 使用派生类类型作为基类的泛型操作的参数,c#,generics,inheritance,action,C#,Generics,Inheritance,Action,我想通过委托操作一个实例,委托是类本身的一个属性。委托的参数应该始终是实例本身(即使在派生类中也是如此!) 请参阅下面的代码。我知道代码没有编译,因为我必须将car1转换为car类型,我正在寻找一种不转换的解决方案 代码 static void Main(字符串[]args) { var car=新车(); car.VehicleManipulator=car1=>car1.SomeInt++; 汽车。操纵汽车(); 控制台。写入线(“结束”); Console.ReadLine(); } 内级

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

请参阅下面的代码。我知道代码没有编译,因为我必须将car1转换为car类型,我正在寻找一种不转换的解决方案

代码

static void Main(字符串[]args)
{
var car=新车();
car.VehicleManipulator=car1=>car1.SomeInt++;
汽车。操纵汽车();
控制台。写入线(“结束”);
Console.ReadLine();
}
内级车
{
公共行动车辆操纵器{get;set;}
公共无效操纵车辆()
{
本车操纵器(本车);
}
}
内部级别车辆:车辆
{
公共int SomeInt{get;set;}
}
编辑: 更改代码


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

您已经接近了。您获得此行
car.manufactiveHicle()的
NullReferenceException
的原因是因为
车辆操纵器
操作为空

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

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

将其从派生类中删除,它将起作用

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


如果您想避免铸造,请将车辆制成通用型,如:

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

class Car : Vehicle<Car> {
    int SomeInt { get; set; }
}
车辆等级,其中T:车辆{
操作操作工具{get;set;}
}
汽车类别:汽车{
int SomeInt{get;set;}
}

这看起来有点奇怪,但这意味着如果你有一个汽车的实例,操纵器在汽车上工作,如果你有一辆卡车,它在卡车上工作,等等。交通工具应该是抽象的

哪里有问题?如果出现问题,您可以使用所有继承类重写的方法。Car.VehicleManipulator操作为null,您从未分配过它,将其设为虚拟,编译器将在派生类中查找实现classes@A.T.相反,属性被赋值,但方法使用基类的属性。这不是关于空值,而是关于inheritance@Snowcrack-通过仅移除派生属性中的属性,您没有进行强制转换。这就是继承的第一个概念——在基类上添加更多的内容。为什么要在派生类中使用另一个相同类型和名称的属性?您在派生类中重新引入了
VehicleManipulator
,这是有意的吗?你知道这会有什么影响吗?@Snowcrack-这会澄清发生了什么并帮助你解决问题吗?
class Vehicle<T> where T : Vehicle {
     Action<T> ManipulateVehicle { get; set; }
}

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