2011-09-07 63 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 
}));