Just a little niggle about LINQ syntax. I'm flattening an IEnumerable<IEnumerable<T>>
with SelectMany(x => x)
.
My problem is with the lambda expression x => x
. It looks a bit ugly. Is there some static 'identity function' object that I can use instead of x => x
? Something like SelectMany(IdentityFunction)
?
Note: this answer was correct for C# 3, but at some point (C# 4? C# 5?) type inference improved so that the
IdentityFunction
method shown below can be used easily.No, there isn't. It would have to be generic, to start with:
But then type inference wouldn't work, so you'd have to do:
which is a lot uglier than
x => x
.Another possibility is that you wrap this in an extension method:
Unfortunately with generic variance the way it is, that may well fall foul of various cases in C# 3... it wouldn't be applicable to
List<List<string>>
for example. You could make it more generic:But again, you've then got type inference problems, I suspect...
EDIT: To respond to the comments... yes, C# 4 makes this easier. Or rather, it makes the first
Flatten
method more useful than it is in C# 3. Here's an example which works in C# 4, but doesn't work in C# 3 because the compiler can't convert fromList<List<string>>
toIEnumerable<IEnumerable<string>>
:I'd go with a simple class with a single static property and add as many as required down the line
Does this work in the way you want? I realize Jon posted a version of this solution, but he has a second type parameter which is only necessary if the resulting sequence type is different from the source sequence type.
You can get close to what you need. Instead of a regular static function, consider an Extension Method for your
IEnumerable<T>
, as if the identity function is of the collection, not the type (a collection can generate the identity function of its items):with this, you don't have to specify the type again, and write:
This does feel a bit abusive though, and I'd probably go with
x=>x
. Also, you cannot use it fluently (in chaining), so it will not always be useful.Unless I misunderstand the question, the following seems to work fine for me in C# 4:
You can then do the following in your example:
As well as use
Defines.Identity
anywhere you would use a lambda that looks likex => x
.With C# 6.0 and if you reference FSharp.Core you can do:
And then you're free to do: