c# - Linq .Select()/.SelectMany() 自动使用第二个可选参数

标签 c# linq select optional-parameters

我刚刚发现 Linq 中最奇怪的行为:

当调用一元函数时,我喜欢只传递函数名称,所以而不是

var foo = myList.Select(item => MyFunc(item));

我写

var foo = myList.Select(MyFunc);

应该是一样的。只是在某些情况下,事实并非如此!也就是说,如果函数有第二个参数,它是一个 int 且可选:

private string MyFunc(string input, int foo = 0)
{
   ...
}

在本例中,该语句

var foo = myList.Select(MyFunc);

等于

var foo = myList.Select((item, index) => MyFunc(item, index));

如果第二个参数不是可选的或不是 int,编译器会提示,但在这种情况下,它只是偷偷地让您感到惊讶。

还有人遇到过这种情况吗?还有哪些 Linq 表达式以这种方式工作? (到目前为止,.SelectMany() 是这样)。解决这种行为的最优雅的方法是什么(并防止其他人陷入同样的​​陷阱?)

最佳答案

这实际上并不是特定 LINQ 扩展方法的问题,而是如何处理 Func 的可选参数的问题和 Action s,简而言之 - 它们不是,它们被视为常规参数,并且在选择相应的 Func 时省略默认值/Action签名。看看这里Optional Parameters, No overload for 'Employee' matches delegate 'System.Func<Employee>或这里Invoke Func<T1, T2, T3> which has optional parameters? .

换句话说,您的 MyFunc不能用作Func<string, string> ,您必须使用Func<string, int, string> ,在 Select 的情况下恰好作为添加了索引的重载出现。

关于c# - Linq .Select()/.SelectMany() 自动使用第二个可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39638756/

相关文章:

c# - 如何创建向 COM 公开的只读属性?

c# - Azure.Storage.Blob 中是否还有另一个与 MaximumExecutionTime 和 DisableMD5Validation 等效的属性

c# - 我可以采用 string 或 IEnumerable<T>,其中 T 是 string 或 IEnumerable<T> 吗?

c# - 如何直接返回 ILookup(不使用 Dictionary->ILookup 转换器)

mysql - 将 MYSQL 行导出到多个 txt 文件中

C# Linq 合并多个列表?

c# - LINQ 按 List<results> 分组并返回结果

c# - 比较两个 List<T> 并将其合并到新的 List<T> 中

mysql - 选择日期在过去 24 小时内的记录

javascript - 使用 knockout JS 从 select 标签中删除 optionsCaption