LINQ 身份函数 [英] LINQ identity function
问题描述
对 LINQ 语法有点小题大做.我正在使用 SelectMany(x => x)
将 IEnumerable
展平.
Just a little niggle about LINQ syntax. I'm flattening an IEnumerable<IEnumerable<T>>
with SelectMany(x => x)
.
我的问题是 lambda 表达式 x =>x
.它看起来有点丑.是否有一些静态的身份函数"对象可以代替 x => 使用?x
?类似于 SelectMany(IdentityFunction)
?
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)
?
推荐答案
注意:这个答案对于 C# 3 是正确的,但是在某些时候(C# 4?C# 5?)类型推断得到了改进,因此 IdentityFunction<下面显示的/code> 方法很容易使用.
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>())
这比 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);
}
不幸的是,它的通用变化方式很可能与 C# 3 中的各种情况发生冲突……例如,它不适用于 List
.你可以让它更通用:>
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...
回复评论...是的,C# 4 使这更容易.或者更确切地说,它使第一个 Flatten
方法比在 C# 3 中更有用.这是一个在 C# 4 中有效但在 C# 3 中不起作用的示例,因为编译器无法从List
到>
IEnumerable
:
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);
}
}
}
这篇关于LINQ 身份函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!