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
Using Linq to run a method on a collection of objects?
提问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:
如果MyMethod要void应用的方法具有返回类型,则可以通过以下方式应用该方法:
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!

