通过反射访问属性可以显着减少 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;
}
Run Code Online (Sandbox Code Playgroud)
当然可以缓存通过反射获得的字段访问器。我们在 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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
488 次 |
| 最近记录: |