Понадобилось мне недавно поиметь быстрый доступ к скрытым полям и неиндексируемым свойствам классов. "Быстрый" означает "reflection не подойдёт". Собственно, эта фича понадобилась, чтобы немного подускорить NHibernate, с которым по долгу службы я состою в особо близких отношениях
Было решено реализовать это дело через DynamicMethod (помнится, я как-то даже
писал о применимости LCG для O/R-Mapping ToolsАвтор: Oyster
Дата: 02.09.05
). Сначала я, конечно, погуглил, но не нашёл ничего кроме
Dynamic Method Delegates, что мне не совсем подходило. В итоге решился писать свой велосипед.
Получился простенький класс, который умеет делать быстрый get/set для полей и свойств, используя MemberInfo (т.е. MemberInfo прийдётся предварительно получить). Для работы классу необходима
сборка CommonGenerics. Исходник см. в ответе на это сообщение.
Использовать класс можно следующим образом:
// Тестовый классик
public class Chudo
{
string _field = 42;
private int Prop
{
get { return -1; }
set {}
}
}
// ...
Chudo chu = new Chudo();
// Соберём MemberInfo
FieldInfo fi = typeof(Chudo).GetField("_field", BindingFlags.Instance | BindingFlags.NonPublic);
PropertyInfo pi = typeof(Chudo).GetProperty("Prop", BindingFlags.Instance | BindingFlags.NonPublic);
// Получим значение поля/поменяем его
int fieldValue = (int)FastReflectionHelper.GetValue(fi, chu);
FastReflectionHelper.SetValue(fi, chu, 54);
// Со свойством поступим интереснее - получим делегат
// для получения его значения ...
Function<object, object> getter = FastReflectionHelper.GetMemberGetter(pi);
// ... и используем его
string propertyValue = (string)getter(chu);