2013-10-30 50 views
0

我目前正在努力獲得使用memberexpression集合內的項目完成的方法。 我知道如何寫一個memberexpression直接持有集合的成員,但我怎麼能告訴它使用它的基礎類型。Memberexpression對收集項目

private Collection<TestClass> collection { get; set; } 
DoSomethingWithCollection(collection,() => collection.Count); 

private void DoSomethingWithCollection(Collection<TestClass> collection, MemberExpression member) 
{ 
    foreach(var item in collection) 
    { 
     //use reflexion to get the property for each item 
     //based on the memberexpression and work with it 
    } 
} 

我怎麼會需要重寫這段代碼DoSomethingWithCollection的呼叫可以保持基本類型的集合的Memberexpression,所以從「識別TestClass」?

+0

讓我確定我明白了:假設你的'MemberExpression'指向一個屬性'Name'。在這種情況下,您只需要讀取集合中每個項目的'Name'屬性?因爲在你的用例中,你傳入了一個讀取集合本身的屬性的lambda('Count')。 –

+0

那是正確的。我只是在集合中的類的屬性中進行操作。我提供了Count作爲例子,因爲這就是我知道如何處理集合「直接」,但我不知道如何處理底層類型。 –

+0

您是否希望能夠將lambda作爲第二個參數傳入,如您的示例中所示? –

回答

1

在您的意見中,您也詢問了有關設置屬性的問題。也許你真正需要的是像ForEach運營商更廣義的解決方案,進行了一個集合中的每個元素一些行動:

public static void ForEach<TSource>(
    this IEnumerable<TSource> source, 
    Action<TSource> action) 
{ 
    if (source == null) 
     throw new ArgumentNullException("source"); 
    if (action== null) 
     throw new ArgumentNullException("action"); 

    foreach (TSource item in source) 
     action(item); 
} 

現在你能讀一個屬性:

items.ForEach(item => Console.WriteLine(item.Name)); 

.. 。或者設置一個屬性:

items.ForEach(item => item.Name = item.Name.ToUpper()); 

...或做別的事:

items.ForEach(item => SaveToDatabase(item)); 

您可以自己編寫此擴展方法,但它也是交互式擴展的一部分,它通過反應式擴展的幾項功能擴展了LINQ。只需在NuGet上查找「Ix實驗」包。

3

你可以使用泛型來實現這一目標更容易,更有效:

private void DoSomethingWithCollection<TClass, TProperty>(
    Collection<TClass> collection, 
    Func<TClass, TProperty> extractProperty) 
{ 
    foreach (var item in collection) 
    { 
     var value = extractProperty(item); 
    } 
} 

這裏是你如何使用它(考慮您的藏品有一個「名稱」屬性):

DoSomethingWithCollection(collection, item => item.Name); 
+0

感謝您的答案看起來非常好,並且比我的reflecion調用屬性更容易。只是一個簡單的問題,是否可以用這個值來指定一個值,還是僅限於獲取一個值? –

+1

是的,但您需要一個不同的委託類型(一個接受目標對象和值),比如'Action '。然後你可以傳入'(item,value)=> item.Name = value' –

+0

@MikeStrobel:我試圖將代碼改爲你的建議,但是我沒有這麼做。我的方法有以下簽名:DoSomethingWithCollection (IEnumerable 集合,Action setProperty)(如您所推薦的)。我的電話現在是:DoSomethingWithCollection (this。TabAccountLangs,(lang,value)=> lang.TextAccount =「asdfasdf」); - VS告訴我,我必須直接包含。但我不知道如何正確使用setProperty參數。 setProperty(item,???);什麼是第二個參數現在(值?)? –