有没有更快的方法来使用反射访问类的属性成员?

时间:2010-12-22 18:45:50

标签: .net reflection

我目前正在使用以下代码使用反射访问对象的属性:

 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 个答案:

答案 0 :(得分:2)

您可以采取以下几种方式:

  • 使用Expression Trees。您可以将它们编译为委托并缓存它们以供后续使用。
  • 使用Runtime C# Code Compilation
  • 不要采用这种方法。告诉我们你想要达到的目标,有人可以提出更好的解决方案。

答案 1 :(得分: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))之类的查找中以供将来重用,则此方法只会节省时间。

答案 2 :(得分:0)

我不是VB-er,但每次执行此操作时CLR都必须执行查找(这是瓶颈):

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

因此,尝试将其结果缓存在静态/共享变量中,然后单独调用它:

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