2015-10-05 132 views
9

考慮下面的代碼投射動態對象使用反射鍵入C#

var currentType = Type.GetType("Some.Type, Some"); 
dynamic myDynamic = new System.Dynamic.ExpandoObject(); 
myDynamic.A = "A"; 
var objectInCorrectType = ??? 

我怎麼投的動態的currentType?

+5

你不能。你要麼做一個重新解釋演員,基本上說:「我知道這個引用實際上是一個X僞裝成Y,所以把它轉換爲X,將該引用重新解釋爲對X的引用」,或者做一個包含代碼的轉換進行轉換,例如創建一個新的X和複製值等。沒有內置的方法將ExpandoObject轉換或轉換爲某種特定類型,您需要自己構建它。 –

回答

9

您不能將動態對象轉換爲特定的類型,如@Lasse所述。

然而,你的問題中提到「反思」,所以我懷疑你正在尋找一種方式來簡單地映射屬性值(即「創建一個新的X和複製了值,等等。」在拉塞的評論):

... 
myDynamic.A = "A"; 

// get settable public properties of the type 
var props = currentType.GetProperties(BindingFlags.Public | BindingFlags.Instance) 
    .Where(x => x.GetSetMethod() != null); 

// create an instance of the type 
var obj = Activator.CreateInstance(currentType); 

// set property values using reflection 
var values = (IDictionary<string,object>)myDynamic; 
foreach(var prop in props) 
    prop.SetValue(obj, values[prop.Name]); 
+1

這就是我之後,謝謝:) –

+0

@TimGeyssens如果這是你的答案 - 將它標記爲答案... –

+0

@verarind done :) –

3

dynamicduck-typing一個變量(即延遲類型檢查運行時)。它仍然保存着一個類型化的對象,但它在編譯期間沒有被檢查。

因此,既然ExpandoObject是一種類型,如果您將其分配給類型化或動態引用,則不能將ExpandoObject轉換爲類型,只是因爲它與目標類型共享相同的成員。

順便說一句,因爲ExpandoObject工具IDictionary<string, object>,可以實現某種對即時從ExpandoObject實例映射的,其中一個成員作爲擴展方法匹配到目標類型:

public static class ExpandObjectExtensions 
{ 
    public static TObject ToObject<TObject>(this IDictionary<string, object> someSource, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public) 
      where TObject : class, new() 
    { 
     Contract.Requires(someSource != null); 
     TObject targetObject = new TObject(); 
     Type targetObjectType = typeof (TObject); 

     // Go through all bound target object type properties... 
     foreach (PropertyInfo property in 
        targetObjectType.GetProperties(bindingFlags)) 
     { 
      // ...and check that both the target type property name and its type matches 
      // its counterpart in the ExpandoObject 
      if (someSource.ContainsKey(property.Name) 
       && property.PropertyType == someSource[property.Name].GetType()) 
      { 
       property.SetValue(targetObject, someSource[property.Name]); 
      } 
     } 

     return targetObject; 
    } 
} 

現在,試試下面的代碼,它會按照您期望:

public class A 
{ 
    public int Val1 { get; set; } 
} 

// Somewhere in your app... 
dynamic expando = new ExpandoObject(); 
expando.Val1 = 11; 

// Now you got a new instance of A where its Val1 has been set to 11! 
A instanceOfA = ((ExpandoObject)expando).ToObject<A>(); 

其實,我已經基於其他Q &一個這樣的回答,我可以處理地圖的一個類似的問題ping對象到字典,反之亦然:Mapping object to dictionary and vice versa