【问题标题】:type arguments can't be inferred from the usage for higher-order function无法从高阶函数的用法中推断出类型参数
【发布时间】:2012-06-12 17:24:04
【问题描述】:

我有以下高阶函数:

public static Func<T, bool> Not<T>(Func<T, bool> otherFunc)
{
    return arg => !otherFunc(arg);
}

并试图这样称呼它:

var isValidStr = LinqUtils.Not(string.IsNullOrWhiteSpace);

编译器给了我“无法从用法中推断出类型参数”错误。 但以下工作:

var isValidStr = LinqUtils.Not((string s) => string.IsNullOrWhiteSpace(s));

我想知道有什么区别? string.IsNullOrWhiteSpace 已经是一个具有完全相同签名的非重载函数。

如 cmets 中所述,以下内容也有效,但仍无法解释在这种情况下类型推断失败的原因:

var isValidStr = LinqUtils.Not<string>(string.IsNullOrWhiteSpace);

【问题讨论】:

标签: c# delegates functional-programming higher-order-functions anonymous-delegates


【解决方案1】:

Eric Lippert 在他的博客here 上回答了您正在处理的问题的详细信息。

基本上,正如“David B”在您的 cmets 中所说,“IsNullOrWhiteSpace 是一个方法组。该方法组今天只有一个参与成员,但未来可能会获得更多。”

【讨论】:

  • 很棒的链接。建议的代码是否可以在 c# 4.0 中工作? var isValidStr = LinqUtils.Not(string.IsNullOrWhiteSpace);
  • 不,类型推断改进的升级仅适用于返回类型。
  • 不,它似乎在 C# 4.0 中不起作用 :( 另外,s =&gt; string.IsNullOrWhiteSpace(s) 也不起作用让我认为“方法组”的解释无效。
  • 什么?我没有说它会起作用。我们说的是完全相反。我们是说,类型推断在 3.0 中根本不能将参数作为方法组起作用,而在 4.0 中只适用于返回类型。你的问题正是埃里克在他的博客上所说的。
  • 您的s =&gt; string.IsNullOrEmpty(s) 不会改变您问题的答案。在这种情况下,s 仍然是通用的,无法推断。此示例处理关于 lambdas 中递归类型推断的更复杂的情况。如果你愿意,我可以寻找链接。
【解决方案2】:

这行得通:

var isValidStr = Not<string>(string.IsNullOrWhiteSpace);

虽然,编译器似乎应该有足够的信息来推断这里的类型参数 - 这不应该是必需的......

【讨论】:

  • 我知道。这与我的第二部分基本相同。我想知道为什么类型推断不起作用。
猜你喜欢
  • 2016-05-09
  • 2020-01-24
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多