jjzjj

c# - 补高阶函数

coder 2024-05-29 原文

我正在尝试编写一个补函数,这样当提供函数 f 时,它返回一个函数,当提供与 f 相同的输入时, 返回它的逻辑相反。

将类似的代码放入 VS2017 后,我没有收到任何错误,但我还无法运行代码以查看它是否会按预期工作。我的意图是首先在 repl 中尝试这个,看看它是否会按预期进行。我在那里使用的代码是这样的:

   public static Func<T, bool> Complement<T>(Func<T, bool> f)
   {
       return (T x) => !f(x);
   }

   public static bool GreaterThanTwo (int x) {
     return x > 2;
   }

   static public void Main(string[] args)
   {
     Func<int, bool> NotGreaterThanTwo = Complement(GreaterThanTwo);
     Console.WriteLine(NotGreaterThanTwo(1));
   }

Here is a link to the same.

在 repl 中,我得到错误:

main.cs(17,42): error CS0411: The type arguments for method `MainClass.Complement(System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly Compilation failed: 1 error(s), 0 warnings compiler exit status 1

我看过几个关于堆栈溢出的问题,它们都包含相同的错误消息,例如 thisthis ,但我看不出它们与我遇到的这个问题有什么关系。

最佳答案

Complement(GreaterThanTwo)正在尝试使用 a method group , 不是 Func<int,bool>代表。这失败了,因为 Complement<T>需要一个通用委托(delegate)。

调用将编译为 Func<int,bool> ,例如:

Func<int,bool> cmp= x=>x > 2;
var NotGreaterThanTwo = Complement(cmp);

有一个 implicit conversion from method groups to delegates这意味着这也有效:

Func<int,bool> cmp= GreaterThanTwo;
var NotGreaterThanTwo = Complement(cmp);

这提出了为什么原始代码不起作用的问题? 显式转换也有效:

var NotGreaterThanTwo = Complement((Func<int,bool>)GreaterThanTwo);

方法组表示一组 重载方法,而不仅仅是一个方法。这意味着编译器必须能够找到哪些可用组以在任何情况下使用。

其余的都是假设,因为我还没有找到关于这个具体案例的明确引用或设计说明。

前两个method group conversion rules可能解释出了什么问题:

  • A single method M is selected corresponding to a method invocation (Method invocations) of the form E(A), with the following modifications:

    • The argument list A is a list of expressions, each classified as a variable and with the type and modifier (ref or out) of the corresponding parameter in the formal_parameter_list of D.
    • The candidate methods considered are only those methods that are applicable in their normal form (Applicable function member), not those applicable only in their expanded form.
  • If the algorithm of Method invocations produces an error, then a compile-time error occurs. Otherwise the algorithm produces a single best method M having the same number of parameters as D and the conversion is considered to exist.

Complement<T>(Func<T, bool> f)没有调用,所以编译器不知道要选择和转换组中的哪个方法。它甚至不知道什么T是,所以它不知道该组中的任何方法是否匹配。

另一方面这行得通:

var xx=new []{1,2,3}.Where(GreaterThanTwo);

不过在这种情况下,Where的签名是:

public static System.Collections.Generic.IEnumerable<TSource> Where<TSource> (
    this System.Collections.Generic.IEnumerable<TSource> source, 
    Func<TSource,bool> predicate);

并且类型参数已经可以从 IEnumerable<TSource> 获得.

关于c# - 补高阶函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56681478/

有关c# - 补高阶函数的更多相关文章

  1. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  6. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

  10. ruby - 在 ruby​​ 中使用 .try 函数和 .map 函数 - 2

    我需要从json记录中获取一些值并像下面这样提取curr_json_doc['title']['genre'].map{|s|s['name']}.join(',')但对于某些记录,curr_json_doc['title']['genre']可以为空。所以我想对map和join()使用try函数。我试过如下curr_json_doc['title']['genre'].try(:map,{|s|s['name']}).try(:join,(','))但是没用。 最佳答案 你没有正确传递block。block被传递给参数括号外的方法

随机推荐