2011-12-17 66 views
0

我想寫一個代碼,可以通過lambda表達式設置屬性值。如何避免c#泛型類型將其更改爲基類類型?

「屬性'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型轉換到武器STRING,MemberExpression propertyExp = Expression.Property(targetExp, property);語句將拋出一個異常「屬性‘System.String名稱’沒有爲類型‘UniTest.weapon’定義」 。

在我看來,用通過武器參數調用SetPropertyValueByLambda<K, V>方法,K可以是SWORD類型。如果我改變SetPropertyValueByLambda(weapon, "sword", propInfo);到反射方法:propInfo.SetValue(weapon, "sword", null);會成功。

那麼我能做些什麼讓上面的代碼可以在lambda表達式.thinks中運行。

順便說一句,我不能將名稱屬性從劍類移動到武器類。

+2

我覺得我感覺不舒服。 – x0n 2011-12-17 19:27:31

+0

你爲什麼決定使用反射? – sq33G 2011-12-17 19:42:57

回答

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) 

變量「武器」的類型是「武器」不定義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) 

我意識到這並不能解決您的問題,但這裏的底層問題是您的對象模型。如果你需要一般地與你的對象進行交互,那麼他們需要共享一個通用接口來定義你想要使用的屬性/方法。

+0

你的意思是他們必須有一個共同的界面。 – rcdmk 2011-12-17 18:39:36

+0

@rcdmk - 是的,謝謝。最近在WCF上玩的太多:) – 2011-12-17 18:41:16

+0

@ babcock,thanks.actually,武器武器=新劍()這裏是我的動態創建對象的一個​​實例,它全部繼承了一個武器,我不知道哪個類繼承了武器,之後實例中,我需要爲它設置值,它類似於.NET中的ConfigurationElement和ConfigurationManager.GetSection。 – springchun 2011-12-17 18:45:49