這是比較容易地創建一個lambda函數將從對象返回屬性的值,甚至包括深性質拉姆達行動......創建一個從函數表達式
Func<Category, string> getCategoryName = new Func<Category, string>(c => c.Name);
,這可以被稱爲如下...
string categoryName = getCategoryName(this.category);
但是,鑑於僅上述所得的函數(或原本用於創建函數的表達式),任何人可以提供一種簡單的方法來建立相對的動作......
Action<Category, string> setCategoryName = new Action<Category, string>((c, s) => c.Name = s);
...這將使相同的屬性值,如下所示進行設置?
setCategoryName(this.category, "");
請注意,我在尋找一種方式,從功能或表達編程方式創建的動作 - 我希望我已經表明我已經知道如何手動創建它。
我很樂意接受在.net 3.5和4.0中工作的答案。
謝謝。
UPDATE:
也許我不是在清楚我的問題,所以讓我嘗試和更清楚地表明什麼,我試圖做的。
我有以下的方法(即我對這個問題的目的而創建)...
void DoLambdaStuff<TObject, TValue>(TObject obj, Expression<Func<TObject, TValue>> expression) {
Func<TObject, TValue> getValue = expression.Compile();
TValue stuff = getValue(obj);
Expression<Action<TObject, TValue>> assignmentExpression = (o, v) => Expression<TObject>.Assign(expression, Expression.Constant(v, typeof(TValue)));
Action<TObject, TValue> setValue = assignmentExpression.Compile();
setValue(obj, stuff);
}
我在找的是我怎麼在代碼中創建「assignmentExpression」,使我可以將它編譯成setValue?我認爲它與Expression.Assign有關,但我根本無法制定正確的參數組合來完成代碼。
最終的結果是能夠調用
Category category = *<get object from somewhere>*;
this.DoLambdaStuff(category, c => c.Name);
,這反過來將創造一個getter和類別對象的「名稱」屬性的設置。
上面的版本編譯,但是當我調用setValue()時,它會導致一個ArgumentException,並且「表達式必須是可寫的」。
再次感謝。
我真的不明白你這樣做手動自動反對的意思。但是,如果要設置屬性並決定要在運行時設置哪個屬性,則應使用反射。而且,您可以使用表達式樹來構建運行時lambda表達式。 – Henri 2010-05-15 16:27:01