如何在 C# 中使用作为从相同 class 继承的类型实例的专用对象列表?

How to use a list of specialized objects being instances of types that inherits from the same class in C#?

假设我有 classes Bus 和 Truck,它们继承自 Vehicle:

class Vehicle
{
    public string Model { get; set; }
}
class Bus : Vehicle 
{
    public Bus(string model, int passengers)
    {
        Model = model;
        MaxPassengers = passengers;
    }
    public int MaxPassengers { get; set; }
}
class Truck : Vehicle
{
    public Truck(string model, int weight)
    {
        Model = model;
        MaxWeight = weight;
    }
    public int MaxWeight { get; set; }
}

也就是说,我想让用户创建新的 Truck 或 Bus classes 并保存它们。我能想到的最好方法是制作一个列表,但我必须让它同时接受卡车和巴士对象。

起初我想做一个车辆清单。这是我想出的:

class Program
{
    static void Main(string[] args)
    {
        List<Vehicle> allVehicles = new List<Vehicle>();

        Console.Write("[Bus] Insert model: ");
        string busModel = Console.ReadLine();

        Console.Write("[Bus] Insert max passengers: ");
        int busPassengers = Convert.ToInt32(Console.ReadLine());

        Console.Write("[Truck] Insert model: ");
        string truckModel = Console.ReadLine();

        Console.Write("[Truck] Insert weight capacity: ");
        int truckWeight = Convert.ToInt32(Console.ReadLine());

        allVehicles.Add(new Bus(busModel, busPassengers));
        allVehicles.Add(new Truck(truckModel, truckWeight));
    }
}

上面的代码可以编译,但我无法访问它们的特定属性(Bus 对象的 MaxPassengers 和 Truck 对象的 MaxWeight)。铸造似乎也不起作用。以下语句无法编译:

Console.WriteLine((Bus)allVehicles[0].MaxPassengers);

我错过了什么吗?我是否必须为每个 class 制作一个列表?

使用提供的代码,一切都很好。

您只需为转换添加括号,否则它会尝试转换 MaxPassengers 但失败了:

if ( allVehicles[0] is Bus )
  Console.WriteLine(((Bus)allVehicles[0]).MaxPassengers);

explicitly convert:

if ( allVehicles[0] is Bus )
  Console.WriteLine((allVehicles[0] as Bus).MaxPassengers);

Null-conditional operator 也可以用来避免 if:

Console.WriteLine((allVehicles[0] as Bus)?.MaxPassengers);

您还可以将 pattern-matching 与 C# 7+ 一起使用:

if ( allVehicles[0] is Bus bus)
  Console.WriteLine(bus.MaxPassengers);

您也可以过滤集合:

using System.Linq;

var allBus = allVehicles.OfType<Bus>();

foreach ( var bus in allBus )
  Console.WriteLine(bus.MaxPassengers);