I have an Enumerable & am looking for a method that allows me lớn execute an action for each element, kind of like Select but then for side-effects. Something like:

string<> Names = ...;Names.each(s => Console.Writeline(s));or

Names.each(s => GenHTMLOutput(s)); // (where GenHTMLđầu ra cannot for some reason receive the enumerable itself as a parameter)I did try Select(s=> Console.WriteLine(s); return s; ), but it wasn"t printing anything.

Bạn đang xem: Linq c# là gì




You are looking for the ever-elusive ForEach that currently only exists on the List generic collection. There are many discussions online about whether Microsoft should or should not add this as a LINQ method. Currently, you have sầu lớn roll your own:

public static void ForEach(this IEnumerable value, kích hoạt action) foreach (T cửa nhà in value) action(item); While the All() method provides similar abilities, it"s use-case is for performing a predicate thử nghiệm on every tòa tháp rather than an action. Of course, it can be persuaded to perkhung other tasks but this somewhat changes the semantics và would make it harder for others to lớn interpret your code (i.e. is this use of All() for a predicate chạy thử or an action?).

Improve this answer
answered Feb 9, 2009 at 18:07

Jeff YatesJeff Yates
60k20trăng tròn gold badges136136 silver badges187187 bronze badges
| Show 1 more comment
Disclaimer: This post no longer resembles my original answer, but rather incorporates the some seven years experience I"ve gained since. I made the edit because this is a highly-viewed question & none of the existing answers really covered all the angles. If you want to see my original answer, it"s available in the revision history for this post.

The first thing to lớn understvà here is C# linq operations lượt thích Select(), All(), Where(), etc, have their roots in functional programming. The idea was khổng lồ bring some of the more useful and approachable parts of functional programming khổng lồ the .Net world. This is important, because a key tenet of functional programming is for operations khổng lồ be không tính phí of side effects. It"s hard lớn understate this. However, in the case of ForEach()/each(), side effects are the entire purpose of the operation. Adding each() or ForEach() is not just outside the functional programming scope of the other linq operators, but in direct opposition to lớn them.

But I understvà this feels unsatisfying. It may help explain why ForEach() was omitted from the framework, but fails lớn address the real issue at hvà. You have sầu a real problem you need to solve sầu. Why should all this ivory tower philosophy get in the way of something that might be genuinely useful?

Eric Lippert, who was on the C# thiết kế team at the time, can help us out here. He recommends using a traditional foreach loop:

adds zero new representational power to lớn the language. Doing this lets you rewrite this perfectly clear code:

foreach(Foo foo in foos) statement involving foo;

into this code:

foos.ForEach(foo=> statement involving foo; );

His point is, when you look closely at your syntax options, you don"t gain anything new from a ForEach() extension versus a traditional foreach loop. I partially disagree. Imagine you have this:

foreach(var tác phẩm in Some.Long(& => possibly) .Complicated(set => ofLINQ) .Expression(to lớn => evaluate)) // now do something This code obfuscates meaning, because it separates the foreach từ khóa from the operations in the loop. It also lists the loop command prior lớn the operations that define the sequence on which the loop operates. It feels much more natural lớn want to have sầu those operations come first, và then have the the loop command at the end of the query definition. Also, the code is just ugly. It seems lượt thích it would be much nicer lớn be able to lớn write this:

Some.Long(& => possibly) .Complicated(set => ofLINQ) .Expression(lớn => evaluate) .ForEach(nhà cửa => // now vày something);However, even here, I eventually came around to Eric"s point of view. I realized code like you see above sầu is calling out for an additional variable. If you have sầu a complicated set of LINQ expressions lượt thích that, you can add valuable information to your code by first assigning the result of the LINQ expression to a new variable:

var queryForSomeThing = Some.Long(and => possibly) .Complicated(set => ofLINQ) .Expressions(to => evaluate);foreach(var item in queryForSomeThing) // now vì somethingThis code feels more natural. It puts the foreach keywords back next lớn the rest of the loop, & after the query definition. Most of all, the variable name can add new information that will be helpful to future programmers trying to lớn understvà the purpose of the LINQ query. Again, we see the desired ForEach() operator really added no new expressive sầu power to the language.

However, we are still missing two features of a hypothetical ForEach() extension method:

It"s not composable. I can"t add a further .Where() or GroupBy() or OrderBy() after a foreach loop inline with the rest of the code, without creating a new statement.It"s not lazy. These operations happen immediately. It doesn"t allow me lớn, say, have sầu a khung where a user chooses an operation as one field in a larger screen that is not acted on until the user presses a comm& button. This khung might allow the user khổng lồ change their mind before executing the commvà. This is perfectly normal (easy even) with a LINQ query, but not as simple with a foreach.

(FWIW, most naive .ForEach() implementations also have these issues. But it"s possible lớn craft one without them.)

You could, of course, make your own ForEach() extension method. Several other answers have sầu implementations of this method already; it"s not all that complicated. However, I feel lượt thích it"s unnecessary. There"s already an existing method that fits what we want to vị from both semantic and operational standpoints. Both of the missing features above can be addressed by use of the existing Select() operation.

Xem thêm: Tiểu Sử Biên Đạo Múa Vũ Công John Huy Trần Sinh Năm Bao Nhiêu

Select() fits the kind of transformation or projection described by both of the examples above sầu. Keep in mind, though, that I would still avoid creating side effects. The Gọi to Select() should return either new objects or projections from the originals. This can sometimes be aided through the use of an anonymous type or dynamic object (if & only if necessary). If you need the results khổng lồ persist in, say, an original danh mục variable, you can always Điện thoại tư vấn .ToList() và assign it back to your original variable. I"ll add here that I prefer working with IEnumerable variables as much as possible over more concrete types.

myList = myList.Select(tòa tháp => new SomeType(công trình.value1, vật phẩm.value2 *4)).ToList();In summary:

Just stichồng with foreach most of the time.When foreach really won"t vị (which probably isn"t as often as you think), use Select()When you need to lớn use Select(), you can still generally avoid (program-visible) side effects, possibly by projecting to an anonymous type.Avoid the crutch of calling ToList(). You don"t need it as much as you might think, và it can have significant negative sầu consequence for performance & memory use.