[英]C# Extension method instead of iteration
我想知道,如果有一個擴展方法允許我迭代List並讓我對列表中的每個項目做同樣的事情。 例如:
.RemoveAll(x => x.property == somevalue)
這將刪除滿足條件的每個元素。 但是,如果我有這個:
foreach(object item in lstObjects)
{
object MyObject = new object();
MyObject.propertyone = item.property
MyObject.propertytwo = somevalue;
anotherlist.Add(MyObject);
}
當然,真正的代碼比這復雜一點。 我的目標是,我找到List<T>.ForEach()
而不是foreach
使用擴展方法,但我無法使它工作,並且此方法不存在於var列表中。 我也找到了。選擇.Select<>
.Where<>
在哪里.Where<>
但這會返回值,在我的方法中不需要返回任何值。
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});
我不確定為什么你想要一個擴展方法。 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查詢如何延遲執行並捕獲外部變量,否則這可能會給您帶來奇怪的結果。
編寫自己的ForEach擴展是微不足道的。 我在所有代碼中都包含以下內容:
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action )
{
foreach (T item in collection)
{
action(item);
}
}
您可以通過Select語句完成此操作:
var newList = lstObjects.Select(o =>
new { propertyone = o.property,
propertytwo = somevalue }).ToList();
以下是使用lambda表達式的ForEach
的方法:
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,
}));
List<MyObjectType> list = new List<MyObjectType>();
list.ForEach((MyObjectType item) => {
object MyObject = new object()
{
MyObject.propertyone = item.property,
MyObject.propertytwo = somevalue
};
anotherlist.Add(MyObject);
});
如果要在迭代過程中執行操作,可能需要考慮作為Interactive Extensions一部分的.Do方法。 請參見http://www.thinqlinq.com/Post.aspx/Title/Ix-Interactive-Extensions-return 。
就“內置”而言,沒有.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的原因是因為Microsoft沒有包含它,因為通過設計Linq方法總是返回一個值或值列表。
特別是對你的問題, .Select<T>
將成功。
anotherList.AddRange(lstObjects.Select(x => new MyObject()
{
propertyone = x.property,
propertytwo = somevalue
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.