通过反射访问属性可能会导致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;
}
答案 0 :(得分: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();
}