2010-12-22 51 views
2

我目前使用下面的代碼訪問使用反射物體的屬性:有更快的方式使用反射訪問類的屬性成員嗎?

Dim propInfo As Reflection.PropertyInfo = myType.GetProperty(propName) 
Dim objValue As Object = propInfo.GetValue(myObject, Nothing) 

我有速度,因爲這種類型的代碼被稱爲多次,並造成了一些放緩的一些問題。

我一直在尋找使用Refelction.Emit或動態方法,但我不確定如何使用它們。

背景信息: 我創建了一個對象屬性子集的列表,然後將它與一些元信息相關聯(例如,如果它們可以從數據庫或XML加載,如果它們是可編輯的,用戶看到他們)。這是爲了以後消費,所以我們可以編寫代碼,如:

foreach prop as BaseWrapper in graphNode.NodeProperties 
    prop.LoadFromDataRow(dr) 
next 

該應用程序大量使用有權訪問此列表。問題在於,在項目的初始加載時,正在創建大量的對象,因此對於創建的每個對象都會多次循環訪問此代碼。我最初嘗試手動將每個屬性添加到列表中,但這會遇到問題,並不是所有事情都在正確的時間進行初始化以及其他一些問題。

如果沒有其他好的方法,那麼我可能不得不重新考慮一些設計,看看還有什麼可以做的,以提高性能。

+3

你能說明目標是什麼嗎?也許你不應該使用反思。 – hunter 2010-12-22 18:51:52

回答

2

幾個方法,你可以去:

  • 使用Expression Trees。您可以將它們編譯爲委託並緩存它們以備後續使用。
  • 使用Runtime C# Code Compilation
  • 不要去這個方法。告訴我們你想達到什麼目標,有人可以提出更好的解決方案。
1

您可以使用類似下面的方法來生成將獲得給定對象的屬性的委託。

Public Shared Function CreateGetter(objectType As Type, name As String) As Func(Of Object, Object) 
    Dim param = Expression.Parameter(GetType(Object), "self") 

    Dim expression = Expression.Convert(Expression.[Property](Expression.Convert(param, objectType), name), GetType(Object)) 

    Return Expression.Lambda(Of Func(Of Object, Object))(expression, param).Compile() 
End Function 

您傳遞的屬性定義爲objectType對象的類型和屬性名作爲name。你將被傳回一個Func(Of Object, Object),它將從你傳入的對象中獲取屬性的值,並返回鍵入爲Object的值(如果適用的話)。

請注意,如果您將代理緩存在Dictionary(Of String, Func(Of Object, Object))之類的查找中,以便將來重複使用,此方法只會節省時間。

0

我不是一個VB-ER,但CLR必須執行查找每一個你這樣做(這是瓶頸)時間:

Dim propInfo As Reflection.PropertyInfo = myType.GetProperty(propName) 

所以儘量和緩存的這個結果在靜態/共享變量,只需單獨調用:

Dim objValue As Object = propInfo.GetValue(myObject, Nothing) 
+0

`GetValue`調用也是一個瓶頸 - 與相應的直接獲取屬性的JITed代碼相比,這兩種操作都非常緩慢。 – cdhowie 2010-12-22 19:10:14

相關問題