2012-12-20 16 views
4

我試圖從動態類使用反射來檢索字段或屬性,但是當我使用Getfield或GetProperty調用動態對象時,它永遠找不到該字段,並且沒有動態對象。嘗試*方法被輸入。爲什麼我無法在從DynamicObject繼承的對象上使用GetType()。GetProperty()?

不知道爲什麼這不適用於.net4。

請參閱下面的testdyn動態測試類。

我打電話這樣說:

 dynamic td = new testdyn(); 
     td.SendDebugEvent += new DebugDelegate(debug); 
     td.test(); 

獲取這些結果:

one = -1 
two = -1 
fiddle = -1 
test = -1 
set: fiddle = 241827974 
fiddle = -1 

希望看到

one = 1 
two = 2 
fiddle = 3 
test = -1 
set: fiddle = 241827974 
fiddle = 241827974 

我在做什麼錯?

注意:如果我調用'td.fiddle',它確實有效......但似乎很奇怪您不知道創建該類的名稱,但是您會知道它可以訪問它?

從這篇文章看來,也許反映不支持dynamicobject因爲它實現idynamicmetaobjectprovider

How do I reflect over the members of dynamic object?

的問題是,這個代碼正在被使用反射外部應用程序。

讓我知道你是否有想法。

代碼如下。

public delegate void DebugDelegate(string msg); 
public class testdyn : System.Dynamic.DynamicObject 
    { 
     List<string> items = new List<string>(new string[] { "one", "two", "fiddle", "my", "lou" }); 
     List<int> vals = new List<int>(new int[] { 1,2,3,5,8 }); 

     public event DebugDelegate SendDebugEvent; 
     void debug(string msg) 
     { 
      if (SendDebugEvent!=null) 
       SendDebugEvent(msg); 
     } 

     public void set(string name, int v) 
     { 
      var idx = items.IndexOf(name); 
      if (idx < 0) 
       return; 
      vals[idx] = v; 
      debug("set: " + name + " = " + v); 
     } 

    int get(string name) 
    { 
     object o = null; 
     var t = GetType(); 
     try { 
     o = t.GetProperty(name).GetValue(this, null); 
     int v = (int)o; 
     return v; 
     } catch 
     { 
      try 
      { 
       var f = t.GetField(name); 
       o = f.GetValue(this); 
       return (int)o; 
      } 
      catch 
      { 

      } 
     } 
     return -1; 
    } 

     string g(string name) { return name+" = "+get(name).ToString(); } 
     Random r = new Random(); 
     public void test() { test(string.Empty); } 
     public void test(string mytmp) 
     { 
      var t = GetType(); 
      // do some reads 
      debug(g("one")); 
      debug(g("two")); 
      debug(g("fiddle")); 
      debug(g("test")); 
      // do some sets 
      set("fiddle", r.Next()); 
      // they should change 
      debug(g("fiddle")); 
     } 

     public override bool TryInvokeMember(System.Dynamic.InvokeMemberBinder binder, object[] args, out object result) 
     { 
      debug("got invoke member"); 
      return base.TryInvokeMember(binder, args, out result); 
     } 

     public override bool TrySetMember(System.Dynamic.SetMemberBinder binder, object value) 
     { 
      debug("got setmember"); 
      return base.TrySetMember(binder, value); 
     } 

     public override bool TryGetIndex(System.Dynamic.GetIndexBinder binder, object[] indexes, out object result) 
     { 
      debug("got getindex"); 
      return base.TryGetIndex(binder, indexes, out result); 
     } 

     public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) 
     { 
      // get index of column value trying to be retrieved 
      var idx = items.IndexOf(binder.Name); 
      // default to empty 
      result = string.Empty; 
      // return error if we can't find 
      if (idx < 0) 
      { 
       return base.TryGetMember(binder, out result); 
      } 
      // get result 
      result = vals[idx]; 
      return true; 
     } 

     public override bool TryInvoke(System.Dynamic.InvokeBinder binder, object[] args, out object result) 
     { 
      debug("got invoke"); 
      return base.TryInvoke(binder, args, out result); 
     } 



     public override bool TryCreateInstance(System.Dynamic.CreateInstanceBinder binder, object[] args, out object result) 
     { 
      debug("got create instance"); 
      return base.TryCreateInstance(binder, args, out result); 
     } 

     public override IEnumerable<string> GetDynamicMemberNames() 
     { 
      debug("got member names"); 
      return items.ToArray(); 
     } 
    } 

回答

1

的反思並不動態屬性的作用,(雖然有可能是一個.net4.5例外,如果你實現ICustomTypeProvider

我寫了一個開源的DLR瑞士軍刀切開刀frameworkof各種所謂ImpromptuInterface (在nuget中可用)。其中我有一個靜態方法,旨在橋接動態屬性的外部代碼使用反射動態訪問屬性的確切原因。 Impromptu.ActLikeProperties(this object originalDynamic, IDictionary<string, Type>propertySpec)ActLikeProperties

問題是你需要提供屬性名稱的字典&返回類型到我的方法,然後將結果傳遞給外部api,我的方法通過包裝你的DynamicObject使用發射代理使用dlr轉發該屬性會調用您在字典中描述的從靜態定義到動態類型。

td.ActLikeProperties(new Dictionary<string,type>{{"one":typeof(int)},{"two":typeof(int) },{"fiddle":typeof(int) },{"test":typeof(int) }}); 
相關問題