使用Linq在对象集合上运行方法?

时间:2009-06-23 12:34:57

标签: c# linq

这是一个很长的镜头,我知道......

假设我有一个集合

List<MyClass> objects;

我想在集合中的每个对象上运行相同的方法,有或没有返回值。在Linq之前我会说:

List<ReturnType> results = new List<ReturnType>();
List<int> FormulaResults = new List<int>();
foreach (MyClass obj in objects) {
  results.Add(obj.MyMethod());
  FormulaResults.Add(ApplyFormula(obj));
}

我会能够做到这样的事情:

List<ReturnType> results = new List<ReturnType>();
results.AddRange(objects.Execute(obj => obj.MyMethod())); 
// obviously .Execute() above is fictitious
List<int> FormulaResults = new List<int>();
FormulaResults.AddRange(objects.Execute(obj => ApplyFormula(obj)));

我还没有找到任何可以做到这一点的事情。有这样的事吗?

如果没有像我上面提到的那样通用,至少也许有一种方法可以用于我现在正在处理的目的:我有一个包含一个包装类的对象的集合:

class WrapperClass {
  private WrappedClass wrapped;
  public WrapperClass(WrappedClass wc) {
    this.wrapped = wc;
  }
}

我的代码有一个集合List<WrappedClass> objects,我希望将其转换为List<WrapperClass>。是否有一些聪明的Linq这样做,没有做繁琐的

List<WrapperClass> result = new List<WrapperClass>();
foreach (WrappedClass obj in objects)
  results.Add(new WrapperClass(obj));

...谢谢

6 个答案:

答案 0 :(得分:18)

将:

results.AddRange(objects.Select(obj => ApplyFormula(obj)));

办?

或(更简单)

var results = objects.Select(obj => ApplyFormula(obj)).ToList();

答案 1 :(得分:4)

我认为Select()扩展方法可以做你想要的:

objects.Select( obj => obj.MyMethod() ).ToList(); // produces List<Result> 

objects.Select( obj => ApplyFormula(obj) ).ToList(); // produces List<int>

最后一种情况也是如此:

objects.Select( obj => new WrapperClass( obj ) ).ToList();

如果你想要调用void方法,这里可以使用IEnumerable,它没有ForEach()扩展,可以毫不费力地创建类似的行为。

objects.Select( obj => { obj.SomeVoidMethod(); false; } ).Count();

在对象序列中的每个Select()上调用[false]后,SomeVoidMethod()将生成一系列[obj]值。由于Select()使用延迟执行,我们调用Count()扩展名来强制计算序列中的每个元素。当你想要ForEach()行为之类的东西时,它可以很好地工作。

答案 2 :(得分:2)

如果要应用的方法MyMethod返回类型为T的对象,则可以通过以下方法获取方法结果的IEnumerable<T>

var results = objects.Select(o => o.MyMethod());

如果您要应用的方法MyMethod的返回类型为void,那么您可以通过以下方式应用该方法:

objects.ForEach(o => o.MyMethod());

这假定objects属于通用类型List<>。如果您拥有IEnumerable<>,那么您可以roll your own ForEach扩展方法或首先应用objects.ToList()并使用上述语法。

答案 3 :(得分:1)

C#编译器将LINQ选择映射到.select扩展方法,该方法通过IEnumerable(或我们将在这里忽略的IQueryable)定义。实际上,.Select方法正是你所追求的那种投影函数。

LBushkin是正确的,但你实际上也可以使用LINQ语法......

var query = from o in objects
   select o.MyMethod();

答案 4 :(得分:1)

您还可以使用奇妙的Jon Skeet morelinq library

运行自定义方法

例如,如果你的MyClass上有一个text属性,你需要在运行时使用同一个类的方法进行更改:

objects = objects.Pipe<MyClass>(class => class.Text = class.UpdateText()).ToList();

此方法现在将在列表中的每个对象上实现。我喜欢morelinq!

答案 5 :(得分:0)

http://www.hookedonlinq.com/UpdateOperator.ashx有一个可以使用的扩展Update方法。或者您可以使用其他人发布的select语句。