2009-05-05 47 views
4

我有一個接受任何對象的函數,然後它從它作爲輸入的屬性或字段中獲取值。關於ComponentModel和Reflection

目前,它看起來像這樣:

private string GetFieldValue(object o, Field f) 
{ 
//field.name is name of property or field 
     MemberInfo[] mi = o.GetType().GetMember(field.name, MemberTypes.Field | MemberTypes.Property, 
      BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | 
      BindingFlags.ExactBinding); 

     if (mi.Length == 0) throw new ArgumentException("Field", "Can't find member: " + f.name); 

     Object value; 
     if (mi[0].MemberType == MemberTypes.Property) 
      value = ((PropertyInfo)mi[0]).GetValue(o, null); 
     else value = ((FieldInfo)mi[0]).GetValue(o); 

今天我讀到System.ComponentModel及其XXXDescriptor類。 性能問題時,兩個框架之間有什麼區別(Reflection & ComponentModel)。將使用ComponentModel重寫上述內容會獲得更好的性能還是靈活性?我知道的那兩個唯一的另一個區別是CM支持虛擬屬性。

Ty。

回答

3

TypeDescriptor(在 System.ComponentModel)內部緩存,所以它可以有更好的性能,儘管沒有什麼能阻止你添加緩存到上面的代碼。 TypeDescriptor使用反射,雖然它允許您擴展您的對象並添加未由「真實」屬性和事件支持的屬性和事件。但是,TypeDescriptor不支持字段。

如果我是你,我也沒在意TypeDescriptor的可擴展性功能, ,我很高興能加入自己的高速緩存上的 GetMember頂部,然後 我會堅持與反思。

編輯:標準反射已緩存MemberInfo自2.0以來的對象 - 請參閱MSDN "Using .NET: Avoid Common Performance Pitfalls for Speedier Apps"

+0

TypeDescriptor實際上並不比stanadrd反射做更多的緩存 - 主要的瓶頸是調用,這是緩慢的。但請參閱我的回覆以瞭解如何改進(使用ComponentModel進行定製)。 – 2009-05-05 12:48:01

+0

我一直認爲TypeDescriptor已被緩存(TypeDescriptor類中的MSDN頁面具有「屬性和事件由TypeDescriptor緩存以提高速度」),而反射解析程序集元數據。 – 2009-05-05 12:53:55

+0

是不是反映兌現MemberInfo已經? 來自MSDN:「MemberInfo緩存在.NET Framework 2.0中被延遲填充,這意味着更低的工作集成本和更少的檢索時間。如果知道要獲取的特定方法的名稱,請使用非 - 多種GetXX方法。「 – majkinetor 2009-05-05 13:01:16

6

區別在於ComponentModel是對原始類的抽象。這意味着您可以定義不存在的屬性 - 實際上,這正是如何將列公開爲數據綁定的屬性。使用ComponentModel,你甚至可以在1.1中得到類似「動態」的東西。

您可能認爲這意味着ComponentModel速度較慢;但實際上,您可以利用這種抽象獲得... HyperDescriptor完全是這樣 - 使用Reflection.Emit編寫直接IL來表示屬性,比反射或香草ComponentModel提供更快的訪問速度。

但是,請注意,ComponentModel默認情況下僅限於屬性(不是字段)。您可以通過飛行中的PropertyDescriptor外牆來實現,但這不是一個好主意。 ComponentModel中的「只寫」屬性也沒有太多的地方。