2015-09-01 50 views
3

我有兩個對象具有完全相同的屬性。這裏有一個例子:使用反射並繞過GetValue返回的對象cast box將值賦給動態類型

public class Field<T> 
{ 
    public T Value {get;set;} 
    // more things 
} 

public class MainObject 
{ 
    public string MyStr {get;set;} 
    public int? MyInt {get;set;} 
    public bool? MyBool {get;set;} 
} 

public class MainObjectField 
{ 
    public Field<string> MyStr {get;set;} 
    public Field<int?> MyInt {get;set;} 
    public Field<bool?> MyBool {get;set;} 
} 

我有一個任務來創建基於XPath的指令,我從外部源得到的MainObjectField實例。
作爲任務的一部分,我需要從MainObject的實例中獲取Value

因爲我不知道編譯類型中當前屬性的類型,所以我使用了一個動態變量。

下面是一個簡單的例子(這是代碼看起來像在現實生活中 - 這個例子中,如果簡化後):

MainObject obj = new MainObject 
{ 
    MyBool = true, 
    MyInt = 12, 
    MyStr = "Example" 
}; 

MainObjectField fieldObj = new MainObjectField(); 
var myBool = obj.GetType().GetProperty("MyBool").GetValue(obj); 
var myInt = obj.GetType().GetProperty("MyInt").GetValue(obj); 
var myStr = obj.GetType().GetProperty("MyStr").GetValue(obj); 

dynamic fieldBool = Activator.CreateInstance(typeof(Field<bool?>)); 
dynamic fieldInt = Activator.CreateInstance(typeof(Field<int?>)); 
dynamic fieldString = Activator.CreateInstance(typeof(Field<string>)); 

fieldBool.Value = myBool; // exception 
fieldInt.Value = myInt; // exception 
fieldString.Value = myStr; // exception 

fieldObj.MyBool = fieldBool; 
fieldObj.MyInt = fieldInt; 
fieldObj.MyStr = fieldString; 

現在我得到這個異常:

不能將類型'object'隱式轉換爲'bool?'。一個明確的 轉換不存在(是否缺少強制轉換?)

我明白爲什麼我得到的例外,我試圖找到一個解決辦法。

我知道currentField.Valueval值是假設爲相同的類型。

我的問題是,使用反射(GetValue返回一個object)會自動投射\將該值填入object並且毀掉我的計劃。 我不能轉換爲「正確的」值,因爲我只知道運行時的類型。

我該如何解決這個問題?

+0

很難說出這麼多的代碼丟失是怎麼回事。如果您提供了一個簡短但完整的示例來說明問題,那麼幫助您會容易得多。 –

+0

這段代碼告訴你一種「對象」不是一種類型的布爾...對象val = GetValFromMainObject(); //使用反射 currentField.Value = val; //我在這裏得到一個異常......如果你知道這只是一個布爾就可以投它。如果你事先不知道它需要什麼,那麼你可以使用這種類型的代碼... var val.gettypename = pe()。underlyingsystemtype.name –

+0

@JonSkeet - 我編輯並添加了一個簡單的代碼的代碼示例。謝謝。 –

回答

3

問題是,活頁夾將使用靜態您嘗試分配給該屬性的值的類型 - 而您希望動態執行此操作。所有你需要做的是改變的變量是dynamic類型和它的作品:

dynamic myBool = obj.GetType().GetProperty("MyBool").GetValue(obj); 
dynamic myInt = obj.GetType().GetProperty("MyInt").GetValue(obj); 
dynamic myStr = obj.GetType().GetProperty("MyStr").GetValue(obj); 

基本上,動態類型將與的dynamic編譯時類型的任何表達式工作動態,但將使用編譯期的執行該綁定時的任何其他表達式的時間類型。

+0

我不敢相信我沒有想過這樣做。謝謝你的幫助!! –

+0

@AmirPopovich:不要爲此打動自己 - 當談到動態打字時,有很多微妙之處。如果你只是調用一個方法並將該值作爲參數傳遞,那麼這會更加明顯 - 當然這就是屬性賦值*的有效性。 –