C# 补高阶函数
我试图编写一个补码函数,当提供函数C# 补高阶函数,c#,C#,我试图编写一个补码函数,当提供函数f时,它返回一个函数,当提供与f相同的输入时,它返回逻辑相反的函数 在VS2017中输入了类似的代码后,我没有收到任何错误,但是我还无法运行代码以查看它是否能按预期工作。我的意图是首先在repl中尝试这一点,看看它是否能像预期的那样工作。我在那里使用的代码是: 公共静态函数补码(Func f) { 返回(tx)=>!f(x); } 公共静态布尔值大于2(整数x){ 返回x>2; } 静态公共void Main(字符串[]args) { Func NotGreat
f
时,它返回一个函数,当提供与f
相同的输入时,它返回逻辑相反的函数
在VS2017中输入了类似的代码后,我没有收到任何错误,但是我还无法运行代码以查看它是否能按预期工作。我的意图是首先在repl中尝试这一点,看看它是否能像预期的那样工作。我在那里使用的代码是:
公共静态函数补码(Func f)
{
返回(tx)=>!f(x);
}
公共静态布尔值大于2(整数x){
返回x>2;
}
静态公共void Main(字符串[]args)
{
Func NotGreaterThanTwo=补码(GreaterThanTwo);
控制台写入线(不超过两(1));
}
在repl中,我得到一个错误:
cs(17,42):错误CS0411:方法的类型参数
`无法从中推断MainClass.Complete(System.Func)'
用法。尝试显式指定类型参数
失败:1个错误,0个警告编译器退出状态1
我已经看了一些关于堆栈溢出的问题,这些问题涵盖了相同的错误消息,例如和,但我看不出它们与我遇到的这个问题有什么关系。补码(GreaterThanTwo)
正在尝试使用,而不是Func
委托。此操作失败,因为补码
需要一个泛型委托
调用将使用Func
编译,例如:
Func<int,bool> cmp= x=>x > 2;
var NotGreaterThanTwo = Complement(cmp);
但在这种情况下,其中
的签名是:
public static System.Collections.Generic.IEnumerable<TSource> Where<TSource> (
this System.Collections.Generic.IEnumerable<TSource> source,
Func<TSource,bool> predicate);
public static System.Collections.Generic.IEnumerable其中(
此System.Collections.Generic.IEnumerable源,
Func谓词);
并且类型参数已经可以从中获得
方法组是一组方法(可能只有一个)的名称,即理论上ToString
方法可能有多个重载(加上任何扩展方法):ToString()
,ToString(string格式)
,等等-因此ToString
本身就是一个“方法组”
使用时:
Func<int, bool> NotGreaterThanTwo = Complement(GreaterThanTwo);
因此,编译器无法推断您所引用的特定方法,您需要通过解决这种歧义来帮助它
您决定如何解决这个问题取决于您,但这里至少有3个选项:
Complement<int>(GreaterThanTwo);
补码(大于2);
Func<int, bool> greaterThanTwo = GreaterThanTwo;
var notGreaterThanTwo = Complement(greaterThanTwo);
Complement((Func<int, bool>)GreaterThanTwo);
Func greaterThanTwo=greaterThanTwo;
var notGreaterThanTwo=补码(greaterThanTwo);
Func<int, bool> greaterThanTwo = GreaterThanTwo;
var notGreaterThanTwo = Complement(greaterThanTwo);
Complement((Func<int, bool>)GreaterThanTwo);
补码((Func)大于2);
当您在main方法中调用它时,类型系统无法确定是什么,您可以通过指定要补充的输入类型来“帮助”它,例如change
complete(大于2)代码>到补码(大于两个)代码>@OliverRadini这些链接准确地解释了问题所在,应该被认为是重复的。编译器无法推断使用哪种类型作为补码
@OliverRadini,因为我正试图找到Eric Lippert的视频以及2006年答案中的解释。它在MSDN的博客引擎更改后丢失。在任何情况下,实际的答案似乎是补码(大于两个)
试图使用方法组,而不是Func
,如果我们使用显式Func
例如Func gt=大于两个,这会使编译器感到困惑;var不大于2=补码(gt)代码>代码编译类型广播也可以使用:补足((Func)大于两个)
我们同时开始评论,浏览了相同的文档,并在几乎相同的时间发布了基本相同的答案:)非常感谢您提供了全面的答案,这清楚地说明了问题所在here@OliverRadini坦白地说明确的答案将是与Jon Skeet或Eric Lippert的特定规则或解释的链接。我不是语言律师,所以我不确定更深层次的原因。我甚至不会简明扼要地考虑方法组,直到遇到这样的编译错误one@CamiloTerevinto我猜我们经常被这个错误所困扰,以至于我们意识到这并不是那么简单。。。
Func<int, bool> greaterThanTwo = GreaterThanTwo;
var notGreaterThanTwo = Complement(greaterThanTwo);
Complement((Func<int, bool>)GreaterThanTwo);