2011-09-07 61 views
1

我想知道,如果有一個擴展方法,允許我迭代列表,讓我做同樣的事情與列表中的每個項目。例如:C#擴展方法,而不是迭代

.RemoveAll(x => x.property == somevalue) 

這將刪除滿足條件的每個元素。但是,如果我有這個:

foreach(object item in lstObjects) 
{ 
    object MyObject = new object(); 
    MyObject.propertyone = item.property 
    MyObject.propertytwo = somevalue; 
    anotherlist.Add(MyObject); 
} 

當然,真正的代碼比這個複雜一點。我的目標是,而不是foreach使用擴展方法,我發現List<T>.ForEach(),但我無法得到它的工作,並且此方法不存在於var列表中。我也發現.Select<>,.Where<>但這返回值,並在我的方法中不需要返回任何值。

+2

無法正常工作?爲什麼不?這是你想要的。 – bzlm

+0

「我們不是在尋找簡單的方法」 - @BlackCath應該回答:) – stukselbax

+0

嗨! @bzim我的時間不夠用了,所以研究MSDN或例子來解釋爲什麼我的attemptp不工作會消耗時間,至少我沒有。給stukselbax:XD lol – BlackCath

回答

3
var convertedItems = lstObjects.Select(item => 
{ 
    object MyObject = new object(); 
    MyObject.propertyone = item.property 
    MyObject.propertytwo = somevalue; 
    return MyObject; 
}); 

anotherList.AddRange(convertedItems); 

anotherList = convertedItems.ToList(); 

,如果你想讓它更短:

var convertedItems = lstObjects.Select(item => 
    new object {propertyone = item.property, propertytwo = somevalue}); 
+0

@#vc 74:不喜歡。與迭代近似相比,線條數量相同,並且不易讀取。但我不會-1。 –

+0

對於OP:請注意,LINQ懶洋洋地評估了哪些代碼比第一次出現的代碼更符合您的代碼。 – FuleSnabel

+0

@丹尼爾:OP沒有要求更多的可讀性,他要求離開做這個沒有使用foreach。另外vc74的代碼有可鏈接的好處,這是與「LINQ」的主要好處之一。 – FuleSnabel

1

我不知道我明白你爲什麼想在這裏的擴展方法。 List<T>.ForEach()將主要做你喜歡的,但你現有的foreach循環既慣用又可讀。是否有一個原因,你不能只寫一個正常的功能來做到這一點?

public void DoMyThing(IList<object> objects) { 
    foreach (var obj in objects) { 
    someOtherList.Add(new MyObj() { 
     item1 = obj 
    }); 
    } 
} 

一般來說,如果你發現你需要變異項目,不歸你不想使用LINQ或查詢經營者的值。只需使用foreach即可。

編輯:答案提示Select()將這個簡單的代碼工作,但是你陳述

真正的代碼比這

這表明,我認爲你可能有一個稍微複雜一點在迭代過程中改變其他狀態。 Select方法將推遲這個突變,直到序列被物化;這可能會給你奇怪的結果,除非你熟悉LINQ查詢如何推遲執行和捕獲外部變量。

0

編寫自己的ForEach擴展是很簡單的。包括我在我所有的代碼如下:

public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action) 
    { 
     foreach (T item in collection) 
     { 
      action(item); 
     } 
    } 
0

您可以通過Select語句實現這一點:

var newList = lstObjects.Select(o => 
         new { propertyone = o.property, 
          propertytwo = somevalue }).ToList(); 
0

這裏是你如何使用ForEachlambda表達:

lstObjects.ForEach(item => 
{ 
    MyObject obj = new MyObject(); 
    obj.propertyone = item.property; 
    obj.propertytwo = somevalue; 
    anotherlist.Add(obj); 
}); 

但是,正如你所看到的,它看起來與你已有的非常相似!

另外,它看起來對我來說Select你想要做什麼可能是一個更好的匹配:

anotherList.AddRange(lstObjects.Select(item => new MyObject() 
{ 
    propertyone = item.property, 
    obj.propertytwo = somevalue, 
})); 
0
List<MyObjectType> list = new List<MyObjectType>(); 

list.ForEach((MyObjectType item) => { 
    object MyObject = new object() 
    { 
     MyObject.propertyone = item.property, 
     MyObject.propertytwo = somevalue 
    }; 

    anotherlist.Add(MyObject); 
}); 
0

您可以輕鬆創建一個擴展方法來做到這一點:

public IEnumerable<T> RemoveAll(this List<T> list, Func<bool, T> condition) 
{ 
    var itemsToRemove = list.Where(s => condition(s)); 
    list.RemoveAll(itemsToRemove); 
} 

,然後你可以這樣調用它:

myList.RemoveAll(x => x.Property == someValue); 

編輯:這是another method做同樣的。

0

只要'內置'去沒有.ForEach();但是我認爲.Aggregate()將是最合適的選擇(如果你絕對和完全想要一個內置函數)。

lstObjects.Aggregate(anotherList, (targetList, value) => 
    { 
     object MyObject = new object(); 
     MyObject.propertyone = item.property 
     MyObject.propertytwo = somevalue; 
     targetList.Add(MyObject); 
     return targetList; 
    }); 

可以很明顯的只寫自己的擴展方法:

public static IEnumerable<T> Intercept<T>(this IEnumerable<T> values, Action<T> each) 
{ 
    foreach (var item in values) 
    { 
     each(item); 
     yield return item; 
    } 
} 

public static IEnumerable<T> Intercept<T>(this IEnumerable<T> values, Action<T, int> each) 
{ 
    var index = 0; 
    foreach (var item in values) 
    { 
     each(item, index++); 
     yield return item; 
    } 
} 

// ... 
a.Intercept(x => { Console.WriteLine(x); }).Count(); 

注:我不創造像其他人一樣在foreach究其原因,是因爲微軟沒有包括因,通過設計Linq方法總是返回一個值或值的列表。

具體到你的問題,.Select<T>將做的伎倆。

anotherList.AddRange(lstObjects.Select(x => new MyObject() 
{ 
    propertyone = x.property, 
    propertytwo = somevalue 
}));