簡體   English   中英

將派生類傳遞給使用父類C#的方法

[英]Pass derived class to method which use parent class c#

今天,我參加了在向已編寫的代碼中添加靜態方法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;
    }

}
}

問題不在於您要傳遞派生類而不是基類; 那將被允許。 問題是您傳遞的是派生類的可變集合,這是不允許的。

幸運的是,您並未將車輛列表視為完整列表:您僅使用它的一個方面-即其枚舉能力。 因此,可以用IEnumerable<Vehicle>替換List<Vehicle> IEnumerable<Vehicle> ,這要“寬容得多”。 特別是,只要CarVehicle繼承,它就可以讓它傳遞IEnumerable<Car>

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

請注意,使用LINQ無需循環即可產生所需的結果。

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

只需將函數更改為IReadOnlyList<Vehicle> List<Vehicle>類型是IReadOnlyList<Vehicle>IReadOnlyList<Vehicle>是協變的,它接受派生類型的集合:

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

如果這不可能,則可以在將列表傳遞給方法時將其轉換為適當的類型:

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

有關協方差的更多信息: https : //docs.microsoft.com/zh-cn/dotnet/standard/generics/covariance-and-contravariance

您可以轉換列表或使用linq進行轉換。 看看: 這個

你可以做:

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

要么:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM