Мне сказали использовать Reflection.Emit вместо PropertyInfo.GetValue/SetValue, потому что это быстрее. Но я не знаю, что из Reflection.Emit и как использовать его для замены GetValue и SetValue. Может ли кто-нибудь помочь мне в этом?
Reflection.Emit лучше, чем GetValue & SetValue: S
Ответ 1
Просто альтернативный ответ; если вы хотите производительность, но похожий API - рассмотрите HyperDescriptor; это использует Reflection.Emit
снизу (поэтому вам не обязательно), но раскрывается в API PropertyDescriptor
, поэтому вы можете просто использовать:
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
props["Name"].SetValue(obj, "Fred");
DateTime dob = (DateTime)props["DateOfBirth"].GetValue(obj);
Одна строка кода, чтобы включить ее, и обрабатывает все кеширование и т.д.
Ответ 2
Если вы извлекаете/устанавливаете одно и то же свойство много раз, то использование чего-то для создания метода typeafe действительно будет быстрее, чем отражение. Однако я бы предложил использовать Delegate.CreateDelegate
вместо Reflection.Emit. Легче получить право, и это все еще невероятно быстро.
Я использовал это в моей реализации протокольных буферов, и это имело огромное значение vs PropertyInfo.GetValue/SetValue
. Как говорили другие, сделайте это только после того, как докажите, что самый простой способ слишком медленный.
У меня есть сообщение в блоге с более подробной информацией, если вы решите пойти по маршруту CreateDelegate
.
Ответ 3
Используйте PropertyInfo.GetValue/SetValue
Если у вас есть проблемы с производительностью, кешируйте объект PropertyInfo (не повторяйте вызов GetProperty)
Если - и только если - использование рефлексии является узким местом производительности вашего приложения (как показано в профилировщике), используйте Delegate.CreateDelegate
Если - и действительно действительно только если - вы абсолютно уверены, что чтение/запись значений по-прежнему является наихудшим узким местом, чтобы начать изучать забавный мир генерации IL во время выполнения.
Я действительно сомневаюсь, что это того стоит, каждый из этих уровней увеличивает сложность кода, а затем повышает производительность - делайте их только в том случае, если вам нужно.
И если доступ к свойствам во время выполнения - это узкое место вашей производительности, то, вероятно, лучше перейти на время доступа к компиляции (это трудно сделать одновременно и общей, и сверхвысокой производительностью).
Ответ 4
Цель Reflection.Emit полностью отличается от цели PropertyInfo.Get/SetValue. Via Reflection.Emit, вы можете напрямую испускать IL-код, например, в динамически скомпилированные сборки и выполнять этот код. Конечно, этот код может получить доступ к вашим свойствам.
Я серьезно сомневаюсь, что это будет намного быстрее, чем использование PropertyInfo в конце, и это не сделано для этой цели. Вы можете использовать Reflection.Emit как генератор кода для небольшого компилятора, например.
Ответ 5
Использование Reflection.Emit кажется слишком "умным", а также преждевременной оптимизацией. Если вы профилируете свое приложение и обнаруживаете, что GetValue/SetValue Reflection является узким местом, то вы можете рассмотреть возможность оптимизации, но, вероятно, даже не тогда...