[C#] Быстрые аксессоры для полей и свойств через LCG
От: Oyster Украина https://github.com/devoyster
Дата: 27.06.06 12:16
Оценка: 11 (3)
Понадобилось мне недавно поиметь быстрый доступ к скрытым полям и неиндексируемым свойствам классов. "Быстрый" означает "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);
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.