2014-12-18 2 views
1

Доступ к свойствам через отражение может привести к значительному сокращению кода для таких вещей, как ORM, но обычно это довольно медленно. Когда эти свойства автоматически генерируются, поля поддержки всегда находятся в одном и том же положении в структуре, и поэтому теоретически можно быстро получить к ним доступ. В C вы просто кэшируете смещение в нужное поле в структуре и вызываете classpointer + fieldoffset. Есть ли способ (безопасно или нет) вызвать Reflection, чтобы получить это смещение и кэшировать его, и как только мы получим его для доступа к содержимому поля?Возможно ли кэширование рефлексивного доступа к полям поддержки для оптимизации?

Я имею в виду что-то вроде этого (пожалуйста, простите мое плохое знание небезопасных синтаксиса):

public class Data { 
    public double Number { get; set; } 
} 

public class DataAccessor { 
    private static Dictionary<string,int> _offsets; 

    public static object Access(Data obj, string field) { 
     int offset; 
     if (!_offsets.TryGetValue(field, out offset)) { 
      offset = typeof(Data).GetBackingFieldOffset(field); 
      _offsets[field] = offset; 
     } 
     object content; 
     unsafe { 
      fixed(Data* p = obj) { 
       content = *(obj + offset); 
      } 
     } 
     return content; 
    } 

ответ

3

Это, конечно, можно кэшировать поле аксессор, полученное с помощью отражения. Мы широко используем его в StringTemplate 4 для оптимизации конвейера рендеринга. Следующий код показывает, как мы генерируем аксессор делегат для доступа поля:

private static System.Func<object, object> BuildAccessor(FieldInfo field) 
{ 
    ParameterExpression obj = Expression.Parameter(typeof(object), "obj"); 
    UnaryExpression instance = !field.IsStatic ? Expression.Convert(obj, field.DeclaringType) : null; 
    Expression<System.Func<object, object>> expr = Expression.Lambda<System.Func<object, object>>(
    Expression.Convert(
     Expression.Field(instance, field), 
     typeof(object)), 
    obj); 

    return expr.Compile(); 
} 

Ссылка: ObjectModelAdaptor

+0

Ниццы, я не думал о компиляции код, чтобы сделать это, но это делает много смысл. благодаря –

Смежные вопросы