将派生类传递给使用父类c#

时间:2018-05-22 20:09:16

标签: 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>)' 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>'

如何将派生类传递给使用父类使其正常工作的方法?

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;
    }

}
}

4 个答案:

答案 0 :(得分:3)

问题不在于你传递派生类来代替基类;这是允许的。问题是你传递的是派生类的可变项集合,这是不允许的。

幸运的是,您没有将车辆列表视为完整列表:您只使用它的一个方面 - 即,它的枚举能力。因此,您可以将List<Vehicle>替换为IEnumerable<Vehicle>,这是更多的原因&#34;宽容&#34;。特别是,只要IEnumerable<Car>继承自Car,就可以在其位置传递Vehicle

static List<Vehicle> GetMovingVehicles(IEnumerable<Vehicle> vehicles) {
    return vehicles.Where(v => v.Speed != 0).ToList();
}

请注意使用LINQ生成所需的结果而不使用循环。

答案 1 :(得分:1)

---applications:
- name: buyatibm-dev-jltn
  random-route: true
  memory: 256M
  path: ./target/buyatibm-dev.war

答案 2 :(得分:0)

只需更改您的功能即可IReadOnlyList<Vehicle>List<Vehicle>类型是变体,而IReadOnlyList<Vehicle>是变体,它接受派生类型的集合:

static List<Vehicle> getMovingVehicles(IReadOnlyList<Vehicle> vehicles){

如果这不可能,那么您可以在将列表传递给方法时将其转换为适当的类型:

getMovingVehicles(cars.ConvertAll(x => (Vehicle) x));

有关协方差的更多信息:https://docs.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance

答案 3 :(得分:0)

您可以转换列表或使用linq投射它。看看:this

你可以这样做:

List<BaseClass> listOfBaseClass= new List<DerivedClass>().ConvertAll(x => (BaseClass)x);

或者:

List<BaseClass> listOfBaseClass = new List<DerivedClass>().Cast<BaseClass>().ToList();