Есть ли более быстрый способ доступа к члену свойства класса с помощью отражения? - PullRequest
2 голосов
/ 22 декабря 2010

В настоящее время я использую следующий код для доступа к свойству объекта с помощью отражения:

 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 ]

2 голосов
/ 22 декабря 2010

Вы можете пойти несколькими путями:

  • Используйте Expression Trees. Вы можете скомпилировать их для делегатов и кэшировать их для последующего использования.
  • Использование Runtime C# Code Compilation.
  • Не подходи к этому подходу. Скажите нам, чего вы хотите достичь, и кто-то может найти лучшее решение.
1 голос
/ 22 декабря 2010

Вы можете использовать метод, подобный следующему, для генерации делегатов, которые получат свойство данного объекта.

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 голосов
/ 22 декабря 2010

Я не VB-er, но CLR должен выполнять поиск каждый раз, когда вы делаете это (что является узким местом):

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

Так что попробуйте кешировать результат в статической / разделяемой переменной и просто вызвать это отдельно:

 Dim objValue As Object = propInfo.GetValue(myObject, Nothing)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...