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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1032274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:34:48  来源:igfitidea点击:

Using Linq to run a method on a collection of objects?

c#linq

提问by Shaul Behr

This is a long shot, I know...

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

Let's say I have a collection

假设我有一个收藏

List<MyClass> objects;

and I want to run the same method on every object in the collection, with or without a return value. Before Linq I would have said:

我想在集合中的每个对象上运行相同的方法,有或没有返回值。在 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));
}

I would loveto be able to do something like this:

我会到可以做这样的事情:

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)));

I haven't found anything that will do this. Is there such a thing?

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

If there's nothing generic like I've posited above, at least maybe there's a way of doing it for the purposes I'm working on now: I have a collection of one object that has a wrapper class:

如果没有像我上面假设的那样通用,至少也许有一种方法可以实现我现在正在研究的目的:我有一个具有包装类的对象的集合:

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

My code has a collection List<WrappedClass> objectsand I want to convert that to a List<WrapperClass>. Is there some clever Linq way of doing this, without doing the tedious

我的代码有一个集合List<WrappedClass> objects,我想将其转换为List<WrapperClass>. 是否有一些聪明的 Linq 方法可以做到这一点,而无需做繁琐的工作

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

Thanks...

谢谢...

采纳答案by Marc Gravell

Would:

将:

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

do?

做?

or (simpler)

或(更简单)

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

回答by LBushkin

I think that the Select() extension method can do what you're looking for:

我认为 Select() 扩展方法可以满足您的需求:

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

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

Same thing for the last case:

最后一种情况也是如此:

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

If you have a voidmethod which you want to call, here's a trick you can use with IEnumerable, which doesn't have a ForEach() extension, to create a similar behavior without a lot of effort.

如果您有void要调用的方法,这里有一个技巧,您可以将其与没有 ForEach() 扩展名的 IEnumerable 一起使用,以轻松创建类似的行为。

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

The Select()will produce a sequence of [false]values after invoking SomeVoidMethod()on each [obj]in the objects sequence. Since Select()uses deferred execution, we call the Count()extension to force each element in the sequence to be evaluated. It works quite well when you want something like a ForEach()behavior.

调用对象序列中的每个值后,Select()将产生一系列[false]值。由于使用延迟执行,我们调用扩展来强制评估序列中的每个元素。当您想要行为之类的东西时,它非常有效。SomeVoidMethod()[obj]Select()Count()ForEach()

回答by LBushkin

http://www.hookedonlinq.com/UpdateOperator.ashxhas an extended Update method you can use. Or you can use a select statement as posted by others.

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

回答by Martin

The C# compiler maps a LINQ select onto the .Select extension method, defined over IEnumerable (or IQueryable which we'll ignore here). Actually, that .Select method is exactly the kind of projection function that you're after.

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

LBushkin is correct, but you can actually use LINQ syntax as well...

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

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

回答by jason

If the method MyMethodthat you want to apply returns an object of type Tthen you can obtain an IEnumerable<T>of the result of the method via:

如果MyMethod您要应用的方法返回一个类型的对象,T那么您可以IEnumerable<T>通过以下方式获得该方法的结果:

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

If the method MyMethodthat you want to apply has return type voidthen you can apply the method via:

如果MyMethodvoid应用的方法具有返回类型,则可以通过以下方式应用该方法:

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

This assumes that objectsis of generic type List<>. If all you have is an IEnumerable<>then you can roll your ownForEachextension method or apply objects.ToList()first and use the above syntax .

这假定它objects是泛型类型List<>。如果您只有一个,IEnumerable<>那么您可以推出自己的ForEach扩展方法或objects.ToList()先应用并使用上述语法。

回答by Anya Hope

You can also run a custom method using the marvelous Jon Skeet's morelinq library

您还可以使用奇妙的 Jon Skeet 的morelinq 库运行自定义方法

For example if you had a text property on your MyClass that you needed to change in runtime using a method on the same class:

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

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

This method will now be implemented on every object in your list. I love morelinq!

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