如何从列表中访问属性

本文关键字:访问 属性 列表 | 更新日期: 2023-09-27 18:06:09

如果我有以下代码,并且想要迭代车辆列表并显示价格,我如何访问该属性?

    public class Vehicle
    {
        public string Name { get; set; }
        public string Price { get; set; }
    }
    public class ElectricalDriven : Vehicle
    {
        public string SuperChargerCord { get; set; }
    }
    public class GasolinDriven : Vehicle
    {
        public string GasolineTank { get; set; }
    }
        var myListOfVechicles = new List<Vehicle>();
        myListOfVechicles.Add(new ElectricalDriven { Name = "Tesla", Price = "100 000", SuperChargerCord = "Yellow cord"});
        myListOfVechicles.Add(new GasolinDriven { Name = "Ford", Price = "50 000", GasolineTank = "Large VZ Tank"});

        foreach (var row in myListOfVechicles)
        {
            Console.WriteLine($"- {row.Name}");
        }

如何从列表中访问属性

问题是Vehicle没有Value属性,因此您不能以类型安全的方式请求它。

一些选项包括:

  • 覆盖ToString,以便确定显示内容:
  • virtual方法添加到VEhivel like GetDescription that returns a string if you don't want that string to override ToString`
  • Price移动到VehicleElectricalDrivenGasolinDriven都继承自的子类型

如果您想为电动和汽油车定义一个唯一的属性,并能够从通用车辆类中检索其值,您可以声明一个虚拟方法并在继承类中覆盖它:

 public class Vehicle
{
    public string Name { get; set; }
    public virtual string GetCustomProperty() { return string.Empty; }
}
public class ElectricalDriven : Vehicle
{
    public string ElectricalVehicleProperty { get; set; }
    public override string GetCustomProperty() { return ElectricalVehicleProperty; }
}
public class GasolinDriven : Vehicle
{
    public string GasolinVehicleProprety { get; set; }
    public override string GetCustomProperty() { return GasolinVehicleProprety; }
}
class Program
{
    static void Main(string[] args)
    {
        var myListOfVechicles = new List<Vehicle>();
        myListOfVechicles.Add(new ElectricalDriven { Name = "Tesla", ElectricalVehicleProperty = "100 000" });
        myListOfVechicles.Add(new GasolinDriven { Name = "Ford", GasolinVehicleProprety = "50 000" });
        foreach (var row in myListOfVechicles)
        {
            Console.WriteLine("Price: " + row.GetCustomProperty()); //will output 100,000 and 50,000
        }
        Console.Read();
    }
}

在foreach中,您可以使用"is"运算符检查当前"row"是ElectricalDriven还是GasolinDriven,然后将该行强制转换为匹配的具体实现。应该是这样的:

if (row is ElectricalDriven)
{
    Console.WriteLine($"Price: {((ElectricalDriven)row).Price}");
}
else if (row is GasolinDriven)
{
    Console.WriteLine($"Price: {((GasolinDriven)row).Price}");
}

然而,你可以看到,不同的车辆越多,如果就越多。您可能应该在基类或接口中移动price属性。

编辑:看到作者将price属性移动到Vehicle类,您现在可以访问它,就像访问Name属性一样。

这样做:

var myListOfVechicles = new List<Vehicle>();
myListOfVechicles.Add(new ElectricalDriven { Name = "Tesla", Price = "100 000" });
myListOfVechicles.Add(new GasolinDriven { Name = "Ford", Price = "50 000" });

编译器将在隐式地将子类的对象(如ElectricalDriven(转换为基类类型后,将其分配给基类(Vehicle(

要知道,由于这种转换,当您试图访问该对象时,您正在访问一个只有基类成员的对象,该对象只有Name

为了能够访问Price,您需要在访问其成员之前显式地将对象强制转换为子类类型。最简单的例子你可以试试这个:

   string name, price;
    foreach (var item in myListOfVechicles)
    {
        name = item is ElectricalDriven ? 
                       (item as ElectricalDriven).Name : 
                       (item as GasolinDriven).Name;
        price = item is ElectricalDriven ? 
                        (item as ElectricalDriven).Price :
                        (item as GasolinDriven).Price;
        Console.WriteLine($"Name: {name} - Price: {price}");
    }