我正在尝试通过lambda表达式编写一个可以设置属性值的代码。
“属性'System.String Name'未定义为'UniTest.weapon'类型”例外。
public abstract class weapon{}
public class sword:weapon
{
public string Name
{
get;set;
}
}
public static void SetPropertyValueByLambda<K, V>(K obj,V value,PropertyInfo property)
{
ParameterExpression targetExp = Expression.Parameter(typeof(K), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(V), "value");
MemberExpression propertyExp = Expression.Property(targetExp, property);
BinaryExpression assignExp = Expression.Assign(propertyExp, valueExp);
Action<K, V> active = Expression.Lambda<Action<K, V>>
(assignExp, targetExp, valueExp).Compile();
active(obj, value);
}
weapon weapon = new sword();
PropertyInfo propInfo = typeof(sword).GetProperties().Where(K => K.Name == "Name").ToList()[0];
//set value to object
SetPropertyValueByLambda(weapon, "sword", propInfo);
//propInfo.SetValue(weapon, "sword", null);(reflection)
当我调用SetPropertyValueByLambda方法时,K,V类型转换为WEAPON和STRING,MemberExpression propertyExp = Expression.Property(targetExp, property);
语句将抛出“属性'System.String Name'未定义类型'UniTest.weapon'”异常
在我看来,通过武器参数调用SetPropertyValueByLambda<K, V>
方法cand,K可能是SWORD类型。如果我将SetPropertyValueByLambda(weapon, "sword", propInfo);
改为反射方法:propInfo.SetValue(weapon, "sword", null);
将会成功
所以我可以做些什么让上面的代码可以在lambda expression.thinks中运行。
顺便说一句,我无法从Sword类中将Name属性移动到Weapon类。
答案 0 :(得分:1)
问题是您的实施代码:
weapon weapon = new sword();
PropertyInfo propInfo = typeof(sword).GetProperties().Where(K => K.Name == "Name").ToList()[0];
//set value to object
SetPropertyValueByLambda(weapon, "sword", propInfo);
//propInfo.SetValue(weapon, "sword", null);(reflection)
变量'weapon'是'weapon'类型,它没有定义name属性。如果你需要它是一把剑,那就用剑。
sword weapon = new sword();
PropertyInfo propInfo = typeof(sword).GetProperties().Where(K => K.Name == "Name").ToList()[0];
//set value to object
SetPropertyValueByLambda(weapon, "sword", propInfo);
//propInfo.SetValue(weapon, "sword", null);(reflection)
我意识到这并不能解决你的问题,但这里的根本问题是你的对象模型。如果您需要与对象进行一般性交互,那么他们需要共享一个公共接口,该接口定义您希望可用的属性/方法。