2016-09-08 53 views
0

如果我有以下代碼並想迭代車輛列表並顯示價格,我該如何訪問該財產?如何從列表中訪問財產

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}"); 
     } 
+3

爲什麼'價格'定義在'Vechicle'?您可以創建一個暴露'Price'的接口並將其作爲該接口類型的列表,但需要更多的上下文來確定這是否可接受。或者,您可以轉換爲「動態」並依賴運行時檢查。 – juharr

+0

我知道這不是一個答案,但可能你問這個,因爲設計可以有另一個旋轉。可能你希望有一個「有價值的車輛」類,並在那裏定義財產。 – mekoda

+0

在實際使用中,對於「ElectricalDriven」和「GasolinDriven」類將會有不同的屬性,這就是爲什麼...... – MTplus

回答

0

如果要定義電場和汽油車一個獨特的屬性,並能夠檢索來自通用汽車類它的價值,你可以聲明虛擬方法,並在繼承的類重寫它:

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(); 
    } 
} 
+0

非常感謝! – MTplus

1

的問題是,Vehicle一個Value屬性,所以你不能在一個類型安全的方式提出要求。

某些選項:

  • 覆蓋ToString使得確定所顯示的內容:
  • 添加virtual方法VEhivel like GetDescription that returns a string if you don't want that string to override ToString`
  • 移動PriceVehicle或亞型即ElectricalDrivenGasolinDriven都從中繼承而來。
0

在foreach中,您可以使用'is'運算符檢查當前'行'是ElectricalDriven還是GasolinDriven,然後將行轉換爲匹配的具體實現。應該是這樣的:

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

但是,你可以看到更多不同的車輛,更多的ifs。您可能應該在基類或界面中移動price屬性。

編輯:看到作者將價格屬性移動到Vehicle類,您現在可以像訪問Name屬性一樣訪問它。

+1

雖然在技術上是正確的,但有更乾淨的方法可以做到這一點,不需要進行類型檢查/鑄造。 –

+0

@DStanley你是對的。這就是爲什麼我提到,例如,該屬性應該移動到基類。根據給定的程序結構,我試圖回答。 – vmutafov

+0

我已經更新了一個更好的例子的代碼片段。 – MTplus

0

通過這樣做:

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

編譯器將分配子類(如ElectricalDriven)的一個目的是反對基類(車輛)將其隱式轉換爲基類類型。

由於此轉換知道,當您嘗試訪問該對象時,您正在訪問僅具有基類成員的對象,該對象僅爲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}"); 
    }