2017-07-20 80 views
1

我通過字典成方法:分配對象的一類可變

Dictionary<string, object> vehicles

字典的值可以是命名Vehicle類實例或一個類的實例,從Vehicle繼承,命名Truck

我有一個DataTable,然後我使用字段行值來提取字典值,使用反射。

Vehicle v = (Vehicle)vehicles[dt.Rows[0]["Reference"].ToString()] 

PropertyInfo vehicleInfo = typeof(Vehicle).GetProperty("Height"); 
string propertyVal = vehicleInfo.GetValue(t, null).ToString(); 

唯一的問題是,如果我嘗試從類Truck提取字段值和字段不是從Vehicle繼承,然後vehicleInfo不是一個對象,由於是無法獲得的財產。

有沒有一種方法可以動態地使用上述的VehicleTruck類屬性?還是需要完全不同的方法?

+0

你能解釋一下爲什麼你使用反射來訪問'Vehicle'的屬性? – Chris

+1

這個問題真的是*你如何確定你想得到的屬性?*這意味着所有這些類型的知識,這是半連接訪問他們的方式很奇怪。您可能在這裏遇到了X/Y問題。無論你想要完成什麼,最有可能使用不同的方法更好地實現。將它限制爲這個,你可以使用新的[模式匹配語言改進](http://blog.somewhatabstract.com/2017/01/23/c7-pattern-matching/)或更老的'var xy = x as Ÿ; if(x!= null)...'BS ... – Will

回答

2

理想情況下,你會想要確保你已經知道你的對象的類型,以防止問題。如果你有一個物體,你不知道它的類型,你必須檢查它是否是TruckVehicle並查看它具有哪些屬性,這是要解決的根本問題。你不想要一個方法採取object然後試圖找出它是什麼。相反,請修復它,以便參數的類型有意義,並告訴方法需要知道的有關該參數的所有內容。

不知道完整的細節,你可以嘗試這樣的事:

public interface IVehicle 
{ 
    decimal Height {get;} 
} 

這個接口有你所期望的性能。你用這個接口編寫你的所有代碼。

Dictionary<string, IVehicle> vehicles 

從現在開始,你永遠都不會想知道它是什麼東西或者它有哪些屬性。這是一個IVehicle,它告訴你它具有IVehicle的所有屬性。

你仍然有原始問題 - 其他類沒有實現這個接口。您可以調整,以便它們實現接口。例如,

public class TruckToVehicleAdapter : IVehicle 
{ 
    private readonly Truck _truck; 

    public TruckToVehicleAdapter(Truck truck) 
    { 
     _truck = truck; 
    } 

    public decimal Height { get { return _truck.WhateverHeightPropertyThisHas; } } 
} 

這只是一種方法。但總的想法是避免在你不知道它們類型的地方有一堆對象。相反,想想如何把你所擁有的物品和要求它作爲你想要的類型。轉換它,創建一個新對象,像上面的例子那樣編寫一個適配器。但是你會知道你有什麼。

如果出現另一種新類型的對象,則不必修改所有方法以查看對象是否爲MotorcycleRecreationalVehicle。這可能會失控。你可以按照相同的模式。讓所有東西都成爲IVehicle

1

你可以像這樣訪問:

if (vehicle is Truck t) 
    // t.FieldOfTruck 

在車輛的作用,甚至可以反對