C# 将派生类传递给使用父类c的方法#
今天我参加了一个测试,任务是在已经编写的代码中添加静态方法getMovingVehicles。我做的就像你在下面看到的那样,但在通过在线编译器后,我可以看到有如下错误:C# 将派生类传递给使用父类c的方法#,c#,methods,parent,derived,C#,Methods,Parent,Derived,今天我参加了一个测试,任务是在已经编写的代码中添加静态方法getMovingVehicles。我做的就像你在下面看到的那样,但在通过在线编译器后,我可以看到有如下错误: Compilation error (line 28, col 39): The best overloaded method match for 'Rextester.Program.getMovingVehicles(System.Collections.Generic.List<Rextester.Vehicle&g
Compilation error (line 28, col 39): The best overloaded method match for 'Rextester.Program.getMovingVehicles(System.Collections.Generic.List<Rextester.Vehicle>)' has some invalid arguments
Compilation error (line 28, col 57): Argument 1: cannot convert from 'System.Collections.Generic.List<Rextester.Car>' to 'System.Collections.Generic.List<Rextester.Vehicle>'
Compilation error (line 29, col 41): The best overloaded method match for 'Rextester.Program.getMovingVehicles(System.Collections.Generic.List<Rextester.Vehicle>)' has some invalid arguments
Compilation error (line 29, col 59): Argument 1: cannot convert from 'System.Collections.Generic.List<Rextester.Plane>' to 'System.Collections.Generic.List<Rextester.Vehicle>'
编译错误(第28行,第39列):与“Rextester.Program.getMovingVehicles(System.Collections.Generic.List)”匹配的最佳重载方法具有一些无效参数
编译错误(第28行,第57列):参数1:无法从“System.Collections.Generic.List”转换为“System.Collections.Generic.List”
编译错误(第29行,第41列):与“Rextester.Program.getMovingVehicles(System.Collections.Generic.List)”匹配的最佳重载方法具有一些无效参数
编译错误(第29行,第59列):参数1:无法从“System.Collections.Generic.List”转换为“System.Collections.Generic.List”
我应该如何将派生类传递给使用父类使其正确工作的方法
namespace Rextester
{
abstract class Vehicle{
public int Speed;
}
class Car: Vehicle{
public String VIN;
}
class Plane : Vehicle{
public int altitude;
}
public class Program
{
public static void Main(string[] args)
{
var cars= new List<Car>();
var planes = new List<Plane>();
List<Vehicle> movingCars= getMovingVehicles(cars);
List<Vehicle> movingPlanes=getMovingVehicles(planes);
}
static List<Vehicle> getMovingVehicles(List<Vehicle> vehicles){
List<Vehicle> movingVehicles=new List<Vehicle>();
foreach( Vehicle v in vehicles){
if(v.Speed>0)
movingVehicles.Add(v);
}
return movingVehicles;
}
}
}
名称空间测试仪
{
抽象类车辆{
公共交通速度;
}
汽车类别:汽车{
公共字符串VIN;
}
飞机类别:汽车{
公共高度;
}
公共课程
{
公共静态void Main(字符串[]args)
{
var cars=新列表();
var planes=新列表();
列出移动车辆=获取移动车辆(车辆);
列表移动平面=获取移动车辆(平面);
}
静态列表getMovingVehicles(列表车辆){
列表移动车辆=新列表();
foreach(车辆中的车辆v){
如果(v.速度>0)
移动车辆。添加(v);
}
返回移动车辆;
}
}
}
只需将函数更改为。类型为variant,而为co variant,它接受派生类型的集合:
static List<Vehicle> getMovingVehicles(IReadOnlyList<Vehicle> vehicles){
有关协方差的更多信息:问题不在于传递的是派生类而不是基类;这是允许的。问题是您正在传递派生类项的可变集合,这是不允许的 幸运的是,您并没有将车辆列表视为一个完整的列表:您只使用了它的一个方面,即它的枚举能力。因此,您可以将
List
替换为IEnumerable
,这更“宽容”。特别是,只要Car
继承自Vehicle
,它就允许您在其位置传递IEnumerable
:
static List<Vehicle> GetMovingVehicles(IEnumerable<Vehicle> vehicles) {
return vehicles.Where(v => v.Speed != 0).ToList();
}
静态列表GetMovingVehicles(IEnumerable vehicles){
返回车辆。其中(v=>v.速度!=0)。ToList();
}
请注意,使用LINQ可以在不使用循环的情况下生成所需的结果。您可以使用LINQ转换或强制转换列表。看看: 你可以做:
List<BaseClass> listOfBaseClass= new List<DerivedClass>().ConvertAll(x => (BaseClass)x);
List listOfBaseClass=new List().ConvertAll(x=>(基类)x);
或:
List listOfBaseClass=new List().Cast().ToList();
另一个选项是使用通用
静态列表getMovingVehicles(列出车辆),其中T:车辆{
列表移动车辆=新列表();
foreach(车辆中的车辆v){
如果(v.速度>0)
移动车辆。添加(v);
}
返回移动车辆;
}
汽车
和飞机
应该是列表
。了解协方差。您可以使用IReadOnlyList
。了解C#命名约定。公共名称应为大写。相关:这可能是一个单独的问题,但您如何确定IReadOnlyList
是共同变体?你怎么知道列表
不是呢?@Rainbolt接口IReadOnlyList
中的“out
”表示协变。使用接口列表
可以看到没有输出
。(如果在中有一个“”,它将是相反的。)接口定义中的类型参数具有out
关键字(IReadOnlyList
),该关键字指定类型是协变的。
List<BaseClass> listOfBaseClass= new List<DerivedClass>().ConvertAll(x => (BaseClass)x);
List<BaseClass> listOfBaseClass = new List<DerivedClass>().Cast<BaseClass>().ToList();
Another option is to use a generic
static List<Vehicle> getMovingVehicles<T>(List<T> vehicles) where T:Vehicle {
List<Vehicle> movingVehicles=new List<Vehicle>();
foreach( Vehicle v in vehicles){
if(v.Speed>0)
movingVehicles.Add(v);
}
return movingVehicles;
}