【发布时间】:2012-05-25 19:12:23
【问题描述】:
我想在编译时不知道对象类型的情况下设置对象的属性值;我希望它快(即不每次都使用反射);我知道属性名称和类型。
最快的方法(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' 类型的 ParameterExpression 不能用于'System.Object'类型的委托参数”。
我是表达式树的新手,所以有点迷路了。为什么它不能将 User 转换为 object ?我需要在某个地方进行演员表吗?
“动作”也不好看;只返回一个带参数的委托(用户用户,字符串属性值)会更好。同样,不知道如何做到这一点。实际上,我已经使用 Delegate.CreateDelegate 进行了尝试,但它使用 .Invoke() 方法调用,这很慢(这是唯一的方法吗?);与 Expression.Lambda 相同(非泛型)。
有什么想法吗?
另外,是否有关于表达式树的好的(比 msdn 更好的)文档? msdn 版本确实缺乏细节。
【问题讨论】:
-
TL;DR不要这样做。用相关信息和细节写出简洁明了的问题。 -
已编辑。虽然这是对整个问题的总结,并且有足够的细节来提供答案,imo。
-
这有点偏题了,但感觉就像你是一个习惯使用模板但现在不能在 C# 中使用的 C++ 程序员。这在 C++ 中是微不足道的。
-
User是值类型还是引用类型?