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> objects
and 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 void
method 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 MyMethod
that you want to apply returns an object of type T
then 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 MyMethod
that you want to apply has return type void
then you can apply the method via:
如果MyMethod
要void
应用的方法具有返回类型,则可以通过以下方式应用该方法:
objects.ForEach(o => o.MyMethod());
This assumes that objects
is of generic type List<>
. If all you have is an IEnumerable<>
then you can roll your ownForEach
extension 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!