代码之家  ›  专栏  ›  技术社区  ›  Jakub Mosakowski

将派生类传递给使用父类C的方法#

  •  2
  • Jakub Mosakowski  · 技术社区  · 7 年前

    今天我参加了测试,在哪里的任务是将静态方法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 回复  |  直到 7 年前
        1
  •  1
  •   Venugopal Gopalakrishnapillai    7 年前
    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;
        }
    
        2
  •  3
  •   Sergey Kalinichenko    7 年前

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

    幸运的是,您没有将车辆列表视为完整的列表:您只使用其中的一个方面,即它被枚举的能力。因此,您可以更换 List<Vehicle> 具有 IEnumerable<Vehicle> 更为“宽容”。特别是,它可以让你通过 IEnumerable<Car> 在它的位置上,只要 Car 继承自 Vehicle :

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

    请注意,使用LINQ在不使用循环的情况下生成所需的结果。

        3
  •  0
  •   jspcal    7 年前

    只需改变你的功能 IReadOnlyList<Vehicle> . 这个 List<Vehicle> 类型是变量,而 iReadOnlyList<车辆> 是共同变量,它接受派生类型的集合:

    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

        4
  •  0
  •   FractalCode    7 年前

    您可以转换列表或使用LINQ对其进行强制转换。看看: this

    你可以这样做:

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

    或:

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