Inspired by another question asking about the missing Zip function:
Why is there no ForEach extension method on the IEnumerable interface? Or anywhere? The only class that gets a ForEach method is List<>. Is there a reason why it's missing, maybe performance?
There is already a foreach statement included in the language that does the job most of the time.
I'd hate to see the following:
list.ForEach( item =>
{
item.DoSomething();
} );
Instead of:
foreach(Item item in list)
{
item.DoSomething();
}
The latter is clearer and easier to read in most situations, although maybe a bit longer to type.
However, I must admit I changed my stance on that issue; a ForEach() extension method would indeed be useful in some situations.
Here are the major differences between the statement and the method:
Type checking: foreach is done at runtime, ForEach() is at compile time (Big Plus!)
The syntax to call a delegate is indeed much simpler: objects.ForEach(DoSomething);
ForEach() could be chained: although evilness/usefulness of such a feature is open to discussion.
Those are all great points made by many people here and I can see why people are missing the function. I wouldn't mind Microsoft adding a standard ForEach method in the next framework iteration.
ForEach method was added before LINQ. If you add ForEach extension, it will never be called for List instances because of extension methods constraints. I think the reason it was not added is to not interference with existing one.
However, if you really miss this little nice function, you can roll out your own version
public static void ForEach<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach (T element in source)
action(element);
}
You could write this extension method:
// Possibly call this "Do"
IEnumerable<T> Apply<T> (this IEnumerable<T> source, Action<T> action)
{
foreach (var e in source)
{
action(e);
yield return e;
}
}
Pros
Allows chaining:
MySequence
.Apply(...)
.Apply(...)
.Apply(...);
Cons
It won't actually do anything until you do something to force iteration. For that reason, it shouldn't be called .ForEach(). You could write .ToList() at the end, or you could write this extension method, too:
// possibly call this "Realize"
IEnumerable<T> Done<T> (this IEnumerable<T> source)
{
foreach (var e in source)
{
// do nothing
;
}
return source;
}
This may be too significant a departure from the shipping C# libraries; readers who are not familiar with your extension methods won't know what to make of your code.
The discussion here gives the answer:
Actually, the specific discussion I witnessed did in fact hinge over functional purity. In an expression, there are frequently assumptions made about not having side-effects. Having ForEach is specifically inviting side-effects rather than just putting up with them. -- Keith Farmer (Partner)
Basically the decision was made to keep the extension methods functionally "pure". A ForEach would encourage side-effects when using the Enumerable extension methods, which was not the intent.
While I agree that it's better to use the built-in foreach construct in most cases, I find the use of this variation on the ForEach<> extension to be a little nicer than having to manage the index in a regular foreach myself:
public static int ForEach<T>(this IEnumerable<T> list, Action<int, T> action)
{
if (action == null) throw new ArgumentNullException("action");
var index = 0;
foreach (var elem in list)
action(index++, elem);
return index;
}
Example
var people = new[] { "Moe", "Curly", "Larry" };
people.ForEach((i, p) => Console.WriteLine("Person #{0} is {1}", i, p));
Would give you:
Person #0 is Moe
Person #1 is Curly
Person #2 is Larry
One workaround is to write .ToList().ForEach(x => ...).
pros
Easy to understand - reader only needs to know what ships with C#, not any additional extension methods.
Syntactic noise is very mild (only adds a little extranious code).
Doesn't usually cost extra memory, since a native .ForEach() would have to realize the whole collection, anyway.
cons
Order of operations isn't ideal. I'd rather realize one element, then act on it, then repeat. This code realizes all elements first, then acts on them each in sequence.
If realizing the list throws an exception, you never get to act on a single element.
If the enumeration is infinite (like the natural numbers), you're out of luck.
I've always wondered that myself, that is why that I always carry this with me:
public static void ForEach<T>(this IEnumerable<T> col, Action<T> action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
foreach (var item in col)
{
action(item);
}
}
Nice little extension method.
So there has been a lot of comments about the fact that a ForEach extension method isn't appropriate because it doesn't return a value like the LINQ extension methods. While this is a factual statement, it isn't entirely true.
The LINQ extension methods do all return a value so they can be chained together:
collection.Where(i => i.Name = "hello").Select(i => i.FullName);
However, just because LINQ is implemented using extension methods does not mean that extension methods must be used in the same way and return a value. Writing an extension method to expose common functionality that does not return a value is a perfectly valid use.
The specific arguement about ForEach is that, based on the constraints on extension methods (namely that an extension method will never override an inherited method with the same signature), there may be a situation where the custom extension method is available on all classes that impelement IEnumerable<T> except List<T>. This can cause confusion when the methods start to behave differently depending on whether or not the extension method or the inherit method is being called.
You could use the (chainable, but lazily evaluated) Select, first doing your operation, and then returning identity (or something else if you prefer)
IEnumerable<string> people = new List<string>(){"alica", "bob", "john", "pete"};
people.Select(p => { Console.WriteLine(p); return p; });
You will need to make sure it is still evaluated, either with Count() (the cheapest operation to enumerate afaik) or another operation you needed anyway.
I would love to see it brought in to the standard library though:
static IEnumerable<T> WithLazySideEffect(this IEnumerable<T> src, Action<T> action) {
return src.Select(i => { action(i); return i; } );
}
The above code then becomes people.WithLazySideEffect(p => Console.WriteLine(p)) which is effectively equivalent to foreach, but lazy and chainable.
Note that the MoreLINQ NuGet provides the ForEach extension method you're looking for (as well as a Pipe method which executes the delegate and yields its result). See:
https://www.nuget.org/packages/morelinq
https://code.google.com/p/morelinq/wiki/OperatorsOverview
#Coincoin
The real power of the foreach extension method involves reusability of the Action<> without adding unnecessary methods to your code. Say that you have 10 lists and you want to perform the same logic on them, and a corresponding function doesn't fit into your class and is not reused. Instead of having ten for loops, or a generic function that is obviously a helper that doesn't belong, you can keep all of your logic in one place (the Action<>. So, dozens of lines get replaced with
Action<blah,blah> f = { foo };
List1.ForEach(p => f(p))
List2.ForEach(p => f(p))
etc...
The logic is in one place and you haven't polluted your class.
Most of the LINQ extension methods return results. ForEach does not fit into this pattern as it returns nothing.
If you have F# (which will be in the next version of .NET), you can use
Seq.iter doSomething myIEnumerable
Partially it's because the language designers disagree with it from a philosophical perspective.
Not having (and testing...) a feature is less work than having a feature.
It's not really shorter (there's some passing function cases where it is, but that wouldn't be the primary use).
It's purpose is to have side effects, which isn't what linq is about.
Why have another way to do the same thing as a feature we've already got? (foreach keyword)
https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/
You can use select when you want to return something.
If you don't, you can use ToList first, because you probably don't want to modify anything in the collection.
I wrote a blog post about it:
http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx
You can vote here if you'd like to see this method in .NET 4.0:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=279093
In 3.5, all the extension methods added to IEnumerable are there for LINQ support (notice that they are defined in the System.Linq.Enumerable class). In this post, I explain why foreach doesn't belong in LINQ:
Existing LINQ extension method similar to Parallel.For?
Is it me or is the List<T>.Foreach pretty much been made obsolete by Linq.
Originally there was
foreach(X x in Y)
where Y simply had to be IEnumerable (Pre 2.0), and implement a GetEnumerator().
If you look at the MSIL generated you can see that it is exactly the same as
IEnumerator<int> enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
int i = enumerator.Current;
Console.WriteLine(i);
}
(See http://alski.net/post/0a-for-foreach-forFirst-forLast0a-0a-.aspx for the MSIL)
Then in DotNet2.0 Generics came along and the List. Foreach has always felt to me to be an implementation of the Vistor pattern, (see Design Patterns by Gamma, Helm, Johnson, Vlissides).
Now of course in 3.5 we can instead use a Lambda to the same effect, for an example try
http://dotnet-developments.blogs.techtarget.com/2008/09/02/iterators-lambda-and-linq-oh-my/
I would like to expand on Aku's answer.
If you want to call a method for the sole purpose of it's side-effect without iterating the whole enumerable first you can use this:
private static IEnumerable<T> ForEach<T>(IEnumerable<T> xs, Action<T> f) {
foreach (var x in xs) {
f(x); yield return x;
}
}
My version an extension method which would allow you to use ForEach on IEnumerable of T
public static class EnumerableExtension
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
source.All(x =>
{
action.Invoke(x);
return true;
});
}
}
No one has yet pointed out that ForEach<T> results in compile time type checking where the foreach keyword is runtime checked.
Having done some refactoring where both methods were used in the code, I favor .ForEach, as I had to hunt down test failures / runtime failures to find the foreach problems.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
LINQ equivalent of foreach for IEnumerable<T>
List<T> has a method called ForEach which executes the passed action on each element of it.
var names = new List<String>{ "Bruce", "Alfred", "Tim", "Richard" };
names.ForEach(p => { Console.WriteLine(p); });
But what if names is not a List<T> but an IList<T>? IList<T> doesn't have a method like ForEach.
Is there some alternative?
Use a foreach loop:
foreach (var p in names) {
Console.WriteLine(p);
}
There is no reason to use delegates and extension methods all over the place if that doesn't actually improve readability; a foreach loop is not any less explicitly telling readers what's being done than a ForEach method.
If your IList<T> is an array (T[]), then you have Array.ForEach method on them similar to ForEach on List<T>. You can create an extension method for your custom IList<T> or IEnumerable<T> or whatever you prefer.
public static void ForEach<T>(this IList<T> list, Action<T> action)
{
foreach (T t in list)
action(t);
}
You just have to be wary of the fact that the objects in the original collection will be modified, but I guess the naming does imply that.
------------------------------------------------------------------------------------------------------------------------------------
I prefer to call:
people.Where(p => p.Tenure > 5)
.Select(p => p.Nationality)
.ForEach(n => AssignCitizenShip(n);
than
foreach (var n in people.Where(p => p.Tenure > 5).Select(p => p.Nationality))
{
AssignCitizenShip(n);
}
If so you can create the extension method on IEnumerable. Mind you the terminating call ForEach executes the Linq query. If you do not want it, you can defer it too by using yield statement and returning an IEnumerable<T> back:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T t in list)
{
action(t);
yield return t;
}
}
That solves the side-effect issue, but I personally like a method named ForEach to finally execute the call.
-----------------------------------------------------------------------------------------------------------------------------------
To address the opposing views on preferences, here is a better link from Eric Lippert than this. To quote him:
"The first reason is that doing so violates the functional programming
principles that all the other sequence operators are based upon.
Clearly the sole purpose of a call to this method is to cause side
effects. The purpose of an expression is to compute a value, not to
cause a side effect. The purpose of a statement is to cause a side
effect. The call site of this thing would look an awful lot like an
expression (though, admittedly, since the method is void-returning,
the expression could only be used in a “statement expression”
context.) It does not sit well with me to make the one and only
sequence operator that is only useful for its side effects.
The second reason is that doing so adds zero new representational
power to the language".
Eric's not saying it's a bad thing to do - just the philosophical reasons behind the decision to not include the construct in Linq by default. If you believe a function on an IEnumerable shouldn't act on the contents, then don't do it. Personally I dont mind it since I'm well aware what it does. I treat it as any other method that causes side-effect on a collection class. I can enter into the function and debug it too if I want. Here is another one from Linq itself.
people.Where(p => p.Tenure > 5)
.Select(p => p.Nationality)
.AsParallel()
.ForAll(n => AssignCitizenShip(n);
As I would say, there is nothing bad about these. Its just personal preference. I wouldn't use this for nested foreachs or if it involves more than one line of code to execute inside the foreach loop since thats plain unreadable. But for simple example I posted, I like it. Looks clean and concise.
Edit: See a performance link btw: Why is List<T>.ForEach faster than standard foreach?
You could make an extension method and use most of the implementation of void List<T>.ForEach(Action<T> action). You can download the source code at the Shared Source Initiative site.
Basically you will end to something like this:
public static void ForEach<T>(this IList<T> list, Action<T> action)
{
if (list == null) throw new ArgumentNullException("null");
if (action == null) throw new ArgumentNullException("action");
for (int i = 0; i < list.Count; i++)
{
action(list[i]);
}
}
It is slightly better than the other implementations that use the foreach statement since it takes advantage of the fact that IList includes an indexer.
Although I aggree with the answer of O. R. Mapper, sometimes in big projects with many developers it is hard to convicne everybody that a foreach statement is clearer. Even worse, if your API is based on interfaces (IList) instead of concrete types (List) then developers that are used to the List<T>.ForEach method might start calling ToList on your IList references! I know because it happened in my previous project. I was using the collection interfaces everywhere in our public APIs following the Framework Design Guidelines. It took me a while to notice that many developers where not used to this and call to ToList started apprearing with an alarming rate. Finally I added this extension method to a common assembly that everybody was using and made sure that all unecessary call to ToList were removed from the codebase.
Add this code to static class and call it extensions:
public static void ForEach<T>(this IList<T> list, Action<T> action) {
foreach(var item in list) {
action.Invoke(item);
}
}
When i use a standard Extension Method on a List such as
Where(...)
the result is always IEnumerable, and when
you decide to do a list operation such as Foreach()
we need to Cast(not pretty) or use a ToList() extension method that
(maybe) uses a new List that consumes more memory (is that right?):
List<string> myList=new List<string>(){//some data};
(Edit: this cast on't Work)
myList.Where(p=>p.Length>5).Tolist().Foreach(...);
or
(myList.Where(p=>p.Length>5) as List<string>).Foreach(...);
Which is better code or is there a third way?
Edit:
Foreach is a sample, Replace that with BinarySerach
myList.Where(p=>p.Length>5).Tolist().Binarysearch(...)
The as is definitely not a good approach, and I'd be surprised if it works.
In terms of what is "best", I would propose foreach instead of ForEach:
foreach(var item in myList.Where(p=>p.Length>5)) {
... // do something with item
}
If you desperately want to use list methods, perhaps:
myList.FindAll(p=>p.Length>5).ForEach(...);
or indeed
var result = myList.FindAll(p=>p.Length>5).BinarySearch(...);
but note that this does (unlike the first) require an additional copy of the data, which could be a pain if there are 100,000 items in myList with length above 5.
The reason that LINQ returns IEnumerable<T> is that this (LINQ-to-Objects) is designed to be composable and streaming, which is not possible if you go to a list. For example, a combination of a few where / select etc should not strictly need to create lots of intermediate lists (and indeed, LINQ doesn't).
This is even more important when you consider that not all sequences are bounded; there are infinite sequences, for example:
static IEnumerable<int> GetForever() {
while(true) yield return 42;
}
var thisWorks = GetForever().Take(10).ToList();
as until the ToList it is composing iterators, not generating an intermediate list. There are a few buffered operations, though, like OrderBy, which need to read all the data first. Most LINQ operations are streaming.
One of the design goals for LINQ is to allow composable queries on any supported data type, which is achieved by having return-types specified using generic interfaces rather than concrete classes (such as IEnumerable<T> as you noted). This allows the nuts and bolts to be implemented as needed, either as a concrete class (e.g. WhereEnumerableIterator<T> or hoisted into a SQL query) or using the convenient yield keyword.
Additionally, another design philosophy of LINQ is one of deferred execution. Basically, until you actually use the query, no real work has been done. This allows potentially expensive (or infinite as Mark notes) operations to be completed only exactly as needed.
If List<T>.Where returned another List<T> it would potentially limit composition and would certainly hinder deferred execution (not to mention generate excess memory).
So, looking back at your example, the best way to use the result of the Where operator depends on what you want to do with it!
// This assumes myList has 20,000 entries
// if .Where returned a new list we'd potentially double our memory!
var largeStrings = myList.Where(ss => ss.Length > 100);
foreach (var item in largeStrings)
{
someContainer.Add(item);
}
// or if we supported an IEnumerable<T>
someContainer.AddRange(myList.Where(ss => ss.Length > 100));
If you want to make a simple foreach over a list, you can do like this:
foreach (var item in myList.Where([Where clause]))
{
// Do something with each item.
}
You can't cast (as) IEnumerable<string> to List<string>. IEnumerable evaluates items when you access those. Invoking ToList<string>() will enumerate all items in the collection and returns a new List, which is a bit of memory inefficiency and as well as unnecessary. If you are willing to use ForEach extension method to any collection its better to write a new ForEach extension method that will work on any collection.
public static void ForEach<T>(this IEnumerable<T> enumerableList, Action<T> action)
{
foreach(T item in enumerableList)
{
action(item);
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
LINQ equivalent of foreach for IEnumerable<T>
I'm wondering whether there is a method for IEnumerable like the following .Each() in the .Net library
var intArray = new [] {1, 2, 3, 4};
intArrary.Each(Console.WriteLine);
I know I can use a foreach loop or easily write an extension method like this:
public static class EnumerableExtensions
{
public static void Each<T>(this IEnumerable<T> enumberable, Action<T> action)
{
foreach (var item in enumberable)
{
action(item);
}
}
}
But I'm hoping not to create my own method to mess up code if there is already such an extension method in the library. And something like .Each() (with a few overloadings which can take conditions as extra params) is heavily needed by programmers, and there should already be one. Am I correct?
Update
Ruby developers may recognize it as a .each() iterator. And that's what I hope to have in C#. Maybe C# can have more iterator methods like those in Ruby.
As others have said there is none built in on IEnumerable<T>. The Linq team was against it as per this post by Eric Lippert::
http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx
There is a static method on Array.ForEach and List<T> has an instance method. There is also in PLINQ foreach like statements, but be warned that they work in parallel and can lead to very bad performance for extremely simple actions.
Here is one such method in PLINQ: http://msdn.microsoft.com/en-us/library/dd383744.aspx
And here is a guide on PLINQ in general: http://msdn.microsoft.com/en-us/library/dd460688.aspx
While I can't find the exact article if you poke around in the ParrallelEnumerable section it gives warnings and tips as to how to improve the performance of using parallelism in code
If you want it, I suggest creating 2 versions, one that include indexer and one without. This can be quite useful and can save a select statement to acquire the index.
e.g.
public static void ForEach<T>(IEnumerable<T> enumerable,Action<T> action)
{
foreach(var item in enumerable) action(item);
}
public static void ForEach<T>(IEnumerable<T> enumerable,Action<T,int> action)
{
int index = 0;
foreach(var item in enumerable) action(item,index++);
}
I'd also include argument validation as these are public methods.
Yes there is.
someList.ForEach(x => Console.WriteLine(x));
Or with an array:
Array.ForEach(someArray, x => Console.WriteLine(x));
Note that in this last example you have to call the static method on the Array class
EDIT: The namespaces are: System.Collections.Generic for the List method and System for the Array method
There's a ForEach method on System.Collections.List< T >, but not on IEnumerable. Note, this is also not part of LINQ (it was already there in .NET 2.0).
At first glance you'd expect this to be part of LINQ, as it's sort of an extension on the normal List functionality. However, LINQ is more about grouping, filtering and converting data. If you look closely, most (if not all, I'm not Jon Skeet, I don't know that stuff by heart!) LINQ methods return some sort of IEnumerable.
However, you might want to take a look at MoreLinq. This is an open-source project which adds some key features to the existing LINQ to Objects, one of which is the ForEach method you want (works on any IEnumerable in this case, so it'll work on your array as well).
No, there isn't, unfortunately. (I think this question has been discussed before, but I can't find it currently.)
Due to some bizarre accident of history, the ForEach method ended up on List<T>, instead of IEnumerable<T>, where it would make more sense, and because of backwards-compatiblity, this can never ever be fixed.
Ever since extension methods existed, adding a ForEach(this IEnumerable<T>, ...) extension method was requested over and over again, but it is usually rejected because it would lead to confusing behavior: since instance methods are always selected before extension methods, this would mean that all IEnumerables get treated identically, except for Lists and they wouldn't allow such inconsistencies in the BCL.
As a result, pretty much every .NET project on the planet now starts off with exactly the code you described above:
namespace IEnumerableExtensions
{
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
{
foreach (var x in xs) f(x);
}
}
}
Only List<T> provides a ForEach method - for all other types you will have to roll your own extension method.
it depends on the framework version
.net 3.5 and 4.0 have a ForEach method
I thought it would be nice to do something like this (with the lambda doing a yield return):
public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new()
{
IList<T> list = GetList<T>();
var fun = expression.Compile();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item; // This is not allowed by C#
}
return items.ToList();
}
However, I found out that I can't use yield in anonymous method. I'm wondering why. The yield docs just say it is not allowed.
Since it wasn't allowed I just created List and added the items to it.
Eric Lippert recently wrote a series of blog posts about why yield is not allowed in some cases.
Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
EDIT2:
Part 7 (this one was posted later and specifically addresses this question)
You will probably find the answer there...
EDIT1: this is explained in the comments of Part 5, in Eric's answer to Abhijeet Patel's comment:
Q :
Eric,
Can you also provide some insight into
why "yields" are not allowed inside an
anonymous method or lambda expression
A :
Good question. I would love to have
anonymous iterator blocks. It would be
totally awesome to be able to build
yourself a little sequence generator
in-place that closed over local
variables. The reason why not is
straightforward: the benefits don't
outweigh the costs. The awesomeness of
making sequence generators in-place is
actually pretty small in the grand
scheme of things and nominal methods
do the job well enough in most
scenarios. So the benefits are not
that compelling.
The costs are large. Iterator
rewriting is the most complicated
transformation in the compiler, and
anonymous method rewriting is the
second most complicated. Anonymous
methods can be inside other anonymous
methods, and anonymous methods can be
inside iterator blocks. Therefore,
what we do is first we rewrite all
anonymous methods so that they become
methods of a closure class. This is
the second-last thing the compiler
does before emitting IL for a method.
Once that step is done, the iterator
rewriter can assume that there are no
anonymous methods in the iterator
block; they've all be rewritten
already. Therefore the iterator
rewriter can just concentrate on
rewriting the iterator, without
worrying that there might be an
unrealized anonymous method in there.
Also, iterator blocks never "nest",
unlike anonymous methods. The iterator
rewriter can assume that all iterator
blocks are "top level".
If anonymous methods are allowed to
contain iterator blocks, then both
those assumptions go out the window.
You can have an iterator block that
contains an anonymous method that
contains an anonymous method that
contains an iterator block that
contains an anonymous method, and...
yuck. Now we have to write a rewriting
pass that can handle nested iterator
blocks and nested anonymous methods at
the same time, merging our two most
complicated algorithms into one far
more complicated algorithm. It would
be really hard to design, implement,
and test. We are smart enough to do
so, I'm sure. We've got a smart team
here. But we don't want to take on
that large burden for a "nice to have
but not necessary" feature. -- Eric
Eric Lippert has written an excellent series of articles on the limitations (and design decisions influencing those choices) on iterator blocks
In particular iterator blocks are implemented by some sophisticated compiler code transformations. These transformations would impact with the transformations which happen inside anonymous functions or lambdas such that in certain circumstances they would both try to 'convert' the code into some other construct which was incompatible with the other.
As a result they are forbidden from interaction.
How iterator blocks work under the hood is dealt with well here.
As a simple example of an incompatibility:
public IList<T> GreaterThan<T>(T t)
{
IList<T> list = GetList<T>();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item; // This is not allowed by C#
}
return items.ToList();
}
The compiler is simultaneously wanting to convert this to something like:
// inner class
private class Magic
{
private T t;
private IList<T> list;
private Magic(List<T> list, T t) { this.list = list; this.t = t;}
public IEnumerable<T> DoIt()
{
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
}
}
public IList<T> GreaterThan<T>(T t)
{
var magic = new Magic(GetList<T>(), t)
var items = magic.DoIt();
return items.ToList();
}
and at the same time the iterator aspect is trying to do it's work to make a little state machine. Certain simple examples might work with a fair amount of sanity checking (first dealing with the (possibly arbitrarily) nested closures) then seeing if the very bottom level resulting classes could be transformed into iterator state machines.
However this would be
Quite a lot of work.
Couldn't possibly work in all cases without at the very least the iterator block aspect being able to prevent the closure aspect from applying certain transformations for efficiency (like promoting local variables to instance variables rather than a fully fledged closure class).
If there was even a slight chance of overlap where it was impossible or sufficiently hard to not be implemented then the number of support issues resulting would likely be high since the subtle breaking change would be lost on many users.
It can be very easily worked around.
In your example like so:
public IList<T> Find<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
return FindInner(expression).ToList();
}
private IEnumerable<T> FindInner<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
IList<T> list = GetList<T>();
var fun = expression.Compile();
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
Unfortunately I don't know why they didn't allow this, since of course it's entirely possible to do envision how this would work.
However, anonymous methods are already a piece of "compiler magic" in the sense that the method will be extracted either to a method in the existing class, or even to a whole new class, depending on whether it deals with local variables or not.
Additionally, iterator methods using yield is also implemented using compiler magic.
My guess is that one of these two makes the code un-identifiable to the other piece of magic, and that it was decided to not spend time on making this work for the current versions of the C# compiler. Of course, it might not be a concious choice at all, and that it just doesn't work because nobody thought to implement it.
For a 100% accurate question I would suggest you use the Microsoft Connect site and report a question, I'm sure you'll get something usable in return.
I would do this:
IList<T> list = GetList<T>();
var fun = expression.Compile();
return list.Where(item => fun.Invoke(item)).ToList();
Of course you need the System.Core.dll referenced from .NET 3.5 for the Linq method. And include:
using System.Linq;
Cheers,
Sly
Maybe its just a syntax limitation. In Visual Basic .NET, which is very similar to C#, it is perfectly possible while awkward to write
Sub Main()
Console.Write("x: ")
Dim x = CInt(Console.ReadLine())
For Each elem In Iterator Function()
Dim i = x
Do
Yield i
i += 1
x -= 1
Loop Until i = x + 20
End Function() ' here
Console.WriteLine($"{elem} to {x}")
Next
Console.ReadKey()
End Sub
Also note the parentheses ' here; the lambda function Iterator Function...End Function returns an IEnumerable(Of Integer) but is not such an object by itself. It must be called to get that object, and that’s what the () after End Function does.
The converted code by [1] raises errors in C# 7.3 (CS0149):
static void Main()
{
Console.Write("x: ");
var x = System.Convert.ToInt32(Console.ReadLine());
// ERROR: CS0149 - Method name expected
foreach (var elem in () =>
{
var i = x;
do
{
yield return i;
i += 1;
x -= 1;
}
while (i != x + 20);
}())
Console.WriteLine($"{elem} to {x}");
Console.ReadKey();
}
I strongly disagree to the reason given in the other answers that it's difficult for the compiler to handle. The Iterator Function() you see in the VB.NET example is specifically created for lambda iterators.
In VB, there is the Iterator keyword; it has no C# counterpart. IMHO, there is no real reason this is not a feature of C#.
So if you really, really want anonymous iterator functions, currently use Visual Basic or (I haven't checked it) F#, as stated in a comment of Part #7 in #Thomas Levesque's answer (do Ctrl+F for F#).
I'm learning a bit about function programming, and I'm wondering:
1) If my ForEach extension method is pure? The way I'm calling it seems violate the "don't mess with the object getting passed in", right?
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach ( var item in source )
action(item);
}
static void Main(string[] args)
{
List<Cat> cats = new List<Cat>()
{
new Cat{ Purring=true,Name="Marcus",Age=10},
new Cat{ Purring=false, Name="Fuzzbucket",Age=25 },
new Cat{ Purring=false, Name="Beanhead",Age=9 },
new Cat{Purring=true,Name="Doofus",Age=3}
};
cats.Where(x=>x.Purring==true).ForEach(x =>
{
Console.WriteLine("{0} is a purring cat... purr!", x.Name);
});
// *************************************************
// Does this code make the extension method impure?
// *************************************************
cats.Where(x => x.Purring == false).ForEach(x =>
{
x.Purring = true; // purr,baby
});
// all the cats now purr
cats.Where(x=>x.Purring==true).ForEach(x =>
{
Console.WriteLine("{0} is a purring cat... purr!", x.Name);
});
}
public class Cat {
public bool Purring;
public string Name;
public int Age;
}
2) If it is impure, is it bad code? I personally think it makes cleaner looking code than the old foreach ( var item in items) { blah; }, but I worry that since it might be impure, it could make a mess.
3) Would it be bad code if it returned IEnumerable<T> instead of void? I'd say as long as it is impure, yes it would be very bad code as it would encourage chaining something that would modify the chain. For example, is this bad code?
// possibly bad extension
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach ( var item in source )
action(item);
return source;
}
Impurity doesn't necesarily mean bad code. Many people find it easy and useful to use side effects to solve a problem. The key is first knowing how to do it in a pure way, so you'll know when impurity is appropriate :).
.NET doesn't have the concept of purity in the type system, so a "pure" method that takes in arbitrary delegates can always be impure, depending on how it's called. For instance, "Where", aka "filter", would usually be considered a pure function, since it doesn't modify its arguments or modify global state.
But, there's nothing stopping you from putting such code inside the argument to Where. For example:
things.Where(x => { Console.WriteLine("um?");
return true; })
.Count();
So that's definately an impure usage of Where. Enumerables can do whatever they want as they iterate.
Is your code bad? No. Using a foreach loop is just as "impure" -- you're still modifying the source objects. I write code like that all the time. Chain together some selects, filters, etc., then execute a ForEach on it to invoke some work. You're right, it's cleaner and easier.
Example: ObservableCollection. It has no AddRange method for some reason. So, if I want to add a bunch of things to it, what do I do?
foreach(var x in things.Where(y => y.Foo > 0)) { collection.Add(x)); }
or
things.Where(x => x.Foo > 0).ForEach(collection.Add);
I prefer the second one. At a minimum, I don't see how it can be construed as being worse than the first way.
When is it bad code? When it does side effecting code in a place that's not expected. This is the case for my first example using Where. And even then, there are times when the scope is very limited and the usage is clear.
Chaining ForEach
I've written code that does things like that. To avoid confusion, I would give it another name. The main confusion is "is this immediately evaluated or lazy?". ForEach implies that it'll go execute a loop right away. But something returning an IEnumerable implies that the items will be processed as needed. So I'd suggest giving it another name ("Process", "ModifySeq", "OnEach"... something like that), and making it lazy:
public static IEnumerable<T> OnEach(this IEnumerable<T> src, Action<T> f) {
foreach(var x in src) {
f(x);
yield return x;
}
}
It is not pure, as it can call impure methods. I think by typical definitions, purity is a transitive closure - a function is pure only if all the functions it calls (directly or indirectly) are also pure, or if the effects of those functions are encapsulated (e.g. they only mutate a non-escaping local variable).
Yes, it's not pure, but that's kind of a moot point as it's not even a function.
As the method doesn't return anything, the only option for it to do anything at all is to either affect the objects that you are sending in, or affecting something unrelated (like writing to the console window).
Edit:
To answer your third question; yes, that is bad code, as it seems to be doing something that it doesn't. The method returns a collection so it seems to be pure, but as it just returns the collection that was sent in, it's actually not any more pure than the first version. To make any sense the method should take a Func<T,T> delegate to use as conversion, and return a collection of the converted items:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Func<T,T> converter) {
foreach (T item in source) {
yield return converter(item);
}
}
It's of course still up to the converter function if the extension call is pure. If it doesn't make a copy of the input item but just changes it and returns it, the call is still not pure.
Indeed, because your lambda expression contains an assignment, the function is now by definition impure. Whether the assignment is related to one of the arguments or another object defined outside the current function is irrelevant... A function must have no side-effects whatsoever in order to be called pure. See Wikipedia for a more precise (though quite straightforward) definition, which details the two conditions a function must satisfy to be deemed pure (having no side-effects is one of them). I believe lambda expressions are typically meant to be used as pure functions (at least I would imagine they were originally studied as such from the mathematical perspective), though clearly C# isn't stringent about this, where purely functional languages are. So it's probably not bad pratice, though it's definitely worth being away that such a function is impure.