LINQ identity function
Unless I misunderstand the question, the following seems to work fine for me in C# 4:
public static class Defines
{
public static T Identity<T>(T pValue)
{
return pValue;
}
...
You can then do the following in your example:
var result =
enumerableOfEnumerables
.SelectMany(Defines.Identity);
As well as use Defines.Identity
anywhere you would use a lambda that looks like x => x
.
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:
public static Func<T, T> IdentityFunction<T>()
{
return x => x;
}
But then type inference wouldn't work, so you'd have to do:
SelectMany(Helpers.IdentityFunction<Foo>())
which is a lot uglier than x => x
.
Another possibility is that you wrap this in an extension method:
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
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:
public static IEnumerable<TElement> Flatten<TElement, TWrapper>
(this IEnumerable<TWrapper> source) where TWrapper : IEnumerable<TElement>
{
return source.SelectMany(x => x);
}
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 from List<List<string>>
to IEnumerable<IEnumerable<string>>
:
using System;
using System.Collections.Generic;
using System.Linq;
public static class Extensions
{
public static IEnumerable<T> Flatten<T>
(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(x => x);
}
}
class Test
{
static void Main()
{
List<List<string>> strings = new List<List<string>>
{
new List<string> { "x", "y", "z" },
new List<string> { "0", "1", "2" }
};
foreach (string x in strings.Flatten())
{
Console.WriteLine(x);
}
}
}