我想在编译时不知道对象类型的情况下设置对象的属性值;我希望它快(即不是每次都使用反射);我知道属性名称和类型。
最快的方法(afaik)是使用代表;所以这就是我到目前为止所拥有的:
class User // this is an example.. Assume I don't know which type this is.
{
public string Name {get;set;}
}
public static Action<object, object> CreatePropertySetter(Type targetType, string propertyName)
{
ParameterExpression targetObjParamExpr = Expression.Parameter(targetType);
ParameterExpression valueParamExpr = Expression.Parameter(targetType.GetProperty(propertyName).PropertyType);
MemberExpression propertyExpr = Expression.Property(targetObjParamExpr, propertyName);
BinaryExpression assignExpr = Expression.Assign(targetObjParamExpr, valueParamExpr);
Action<object, object> result = Expression.Lambda<Action<object, object>>(assignExpr, targetObjParamExpr, valueParamExpr).Compile();
return result;
}
然后我会打这个电话:
User user = new User();
var userNameSetter = CreatePropertySetter(user.GetType(), "Name");
userNameSetter(user, "Bob");
但是,它不喜欢我传递 User 类型对象而不是 Object 的事实,并且由于“ 'User' 类型的 ParameterExpression 不能用于'System.Object'类型的委托参数”而失败。
我是表达式树的新手,所以在这里有点迷路。为什么它不能将 User 转换为 object ?我需要在某个地方进行演员表吗?
“动作”看起来也不太好;只返回一个带参数的委托(用户用户,字符串属性值)会更好。同样,不知道如何做到这一点。实际上,我已经用 Delegate.CreateDelegate 尝试过,但它使用 .Invoke() 方法调用,这很慢(这是唯一的方法吗?);与 Expression.Lambda 相同(非泛型)。
有什么想法吗 ?
此外,是否有关于表达式树的好的(比 msdn 更好的)文档?msdn 版本确实缺乏细节。