如何避免c#泛型类型将其更改为基类类型?

时间:2011-12-17 18:29:43

标签: c# lambda

我正在尝试通过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类。

1 个答案:

答案 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)

我意识到这并不能解决你的问题,但这里的根本问题是你的对象模型。如果您需要与对象进行一般性交互,那么他们需要共享一个公共接口,该接口定义您希望可用的属性/方法。