2012-12-04 116 views
0

我們目前正在建立spec流程的測試基礎。所以所有的值都以字符串形式出現。我寫了一些代碼來更新我將使用的Contract對象中的一個屬性。但Contract對象也有一些自定義對象的數組。我想傳入數組的「類型」,該數組中元素的屬性,新值以及要修改的對象的索引。我遇到的問題是獲取一個動態類型的列表,而不僅僅是對象。通過反射更新陣列元素

Contract.cs

public class Contract 
{ 
    public string Name { get; set; } 
    public string Status { get; set; } 

    public Asset[] Asset { get; set; } 
    public Group[] Group { get; set; } 

    public Contract(string name, string status){ 
    Name = name; 
    Status = status 
    Asset = new Asset[ 10 ]; 
    Group = new Group[ 10 ]; 
    } 
} 


Asset.cs

public class Asset { 
     public int ID { get;set;} 
     public string Value {get;set;} 
} 


Group.cs

public class Group{ 
     public int ID { get;set;} 
     public string Value {get;set;} 
} 


那是我的承包商的基本結構T,這裏是客戶端代碼:

static void Main(string[] args) 
{ 
    Contract c = new Contract("TestContract", "Default"); 
    for(int i = 0; i < 10; i++) 
    { 
    c.Asset[ i ] = new Asset(i*10, "base"); 
    c.Group[ i ] = new Group(i*100, "newGroup"); 
    } 

    Console.WriteLine(c); 
    updateContract(c, "Asset", 0, "Value", ".666."); 
    updateContract(c, "Group", 0, "Value", ".999."); 
    updateContract(c, "Group", 2, "Value", ".999."); 
    updateContract(c, "Status", "Awesome"); 
    Console.WriteLine(c);  
} 

public static void updateContract(Contract contract, string collection, int index, string property, string value) 
{ 
    object collectionObject; 
    if(collection == "Asset") 
    { 
     collectionObject = contract.Assets[ index ]; 
    } 
    else if(collection == "Group") 
    { 
     collectionObject = contract.Group[ index ]; 
    } 
    else 
    { 
     throw new Exception("Couldn't parse " + collection + " properly"); 
    } 

    SetPropValue(collectionObject, property, value); 

} 


public static void updateContract(Contract contract, string Property, string value) 
{ 
    SetPropValue(contract, Property, value); 
} 

private static void SetPropValue(object src, string propName, string value) 
{ 
    PropertyInfo pi = src.GetType().GetProperty(propName); 

    //Gets the type of the property passed in 
    Type t = pi.PropertyType; 

    //Converts the string to the property type 
    object newVal = Convert.ChangeType(value, t); 

    //Sets the newly typed object to the property 
    pi.SetValue(src, newVal, BindingFlags.SetProperty, null, null, null); 
    //pi.SetValue(src, newVal); // In .NET 4.5 
} 

基本上我想要刪除的if/else塊,並把這樣的事情在

object[] objectCollections = (object[]) GetPropValue(contract, collection); 
object curCollectionObject = objectCollections[index]; 
SetPropValue(ref curCollectionObject, property, value); 

但多數民衆贊成打破。任何想法或幫助將不勝感激。很抱歉的長期職位

+0

只是有趣的..最簡單的設置值錯誤'c.Asset [0] .Value =「.666。」'? –

+0

,因爲我真的不知道它是否會成爲「資產」或「價值」屬性。他們會從SpecFlow表 – rbucinell

+0

一些字符串行,沒問題。查看下面的解決方案 –

回答

2

無論如何,如果你真的需要通過反射來做到這一點,則:

private static void SetPropValue(object src, string collection, int index, 
           string property, string value) 
{ 
    PropertyInfo collectionProperty = src.GetType().GetProperty(collection); 
    Array array = collectionProperty.GetValue(src, null) as Array; 
    object item = array.GetValue(index); 
    SetPropValue(item, property, value); 
} 

錯誤處理是你的。用法:

SetPropValue(c, "Asset", 2, "Value", ".777."); 
+1

我一直在使用列表和Asset []來回跳轉。我甚至沒有想過這麼簡單的演員,謝謝! – rbucinell