Передать производный класс методу, который использует родительский класс c # - PullRequest
0 голосов
/ 22 мая 2018

Сегодня я принимал участие в тестировании, где стояла задача добавить статический метод 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 голосов
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;
    }
0 голосов
/ 22 мая 2018

Проблема не в том, что вы передаете производный класс вместо базового;это будет разрешено.Проблема в том, что вы передаете изменяемую коллекцию элементов производного класса, что недопустимо.

К счастью, вы не рассматриваете список транспортных средств как полный список: вы используете только один его аспект -а именно, его способность быть перечисленным.Таким образом, вы можете заменить List<Vehicle> на IEnumerable<Vehicle>, что намного более "прощающе".В частности, он позволяет передавать IEnumerable<Car> вместо него, если Car наследуется от Vehicle:

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

Обратите внимание на использование LINQ для получения необходимых результатов без использованияпетля.

0 голосов
/ 22 мая 2018

Вы можете преобразовать список или привести его, используя linq.Взгляните на: это

Вы можете сделать:

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

Или:

List<BaseClass> listOfBaseClass = new List<DerivedClass>().Cast<BaseClass>().ToList();
0 голосов
/ 22 мая 2018

Просто измените свою функцию на 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...