jjzjj

c# - 将成员委托(delegate)给经典函数有更多优点或缺点?

coder 2024-05-23 原文

class my_class
{
    public int add_1(int a, int b) {return a + b;}
    public func<int, int, int> add_2 = (a, b) => {return a + b;}
}

add_1 是一个函数,而 add_2 是一个委托(delegate)。然而,在这种情况下,委托(delegate)可以扮演类似的角色。

由于先例和语言的设计,C# 方法的默认选择应该是函数。

然而,这两种方法各有利弊,所以我列出了一份 list 。这两种方法还有更多优点或缺点吗?

传统方法的优势。

  • 更传统
  • 函数的外部用户看到命名参数 - 对于 add_2 语法 arg_n 和类型通常没有足够的信息。
  • 与 intellisense 配合使用效果更好 - ty Minitech
  • 使用反射 - ty Minitech
  • 与继承一起工作 - ty Eric Lippert
  • 有一个“this” - ty CodeInChaos
  • 更低的开销、速度和内存——来自 Minitech 和 CodeInChaos
  • 在更改和使用函数方面不需要考虑公共(public)\私有(private)。 - ty CodeInChaos
  • 较少动态,允许较少在编译时未知的 - ty CodeInChaos

“委托(delegate)类型字段”方法的优点。

  • 更一致,不是成员函数和数据成员,它只是数据成员。
  • 在外观和行为上都像一个变量。
  • 将其存储在容器中效果很好。
  • 多个类可以使用相同的函数,就好像它是每个类的成员函数一样,这将非常通用、简洁并且具有良好的代码重用。
  • 可以直接在任何地方使用,例如作为本地函数。
  • 大概在通过垃圾收集传递时效果很好。
  • 更动态,在编译时必须知道的更少,例如,可以有在运行时配置对象行为的函数。
  • 好像封装了它的代码,可以组合和修改,msdn.microsoft.com/en-us/library/ms173175%28v=vs.80%29.aspx
  • 函数的外部用户会看到未命名的参数 - 有时这很有用,尽管能够命名它们会很好。
  • 可以更紧凑,在这个简单的示例中,例如可以删除返回,如果有一个参数,也可以删除括号。
  • 你自己的行为,比如继承 - ty Eric Lippert
  • 其他考虑因素,例如功能性、模块化、分布式(代码编写、测试或关于代码的推理)等...

请不要投票关闭,那已经发生了,它已经重新打开了。这是一个有效的问题,即使您认为委托(delegate)方法与既定的编码风格有冲突,或者您不喜欢委托(delegate)的优点,它没有太多实际用途。

最佳答案

首先,对于我来说,关于这个设计决定的“高阶位”是我永远不会用公共(public)字段/方法做这种事情。至少我会使用一个属性,甚至可能不会。

对于私有(private)字段,我经常使用这种模式,通常是这样的:

class C
{
    private Func<int, int> ActualFunction = (int y)=>{ ... };
    private Func<int, int> Function = ActualFunction.Memoize();

现在我可以非常轻松地测试不同记忆化策略的性能特征,而根本无需更改 ActualFunction 的文本。

“方法是委托(delegate)类型的字段”策略的另一个优点是,您可以实现与我们“嵌入”到语言中的技术不同的代码共享技术。委托(delegate)类型的 protected 字段本质上是一个虚方法,但更灵活。派生类可以用他们想要的任何东西替换它,并且您已经模拟了一个常规的虚拟方法。但是您可以构建自定义继承机制;例如,如果你真的喜欢原型(prototype)继承,你可以有一个约定,如果该字段为 null,则调用某个原型(prototype)实例上的方法,等等。

方法是委托(delegate)类型方法的一个主要缺点是,当然,重载不再有效。字段名称必须唯一;方法仅在签名上必须是唯一的。此外,您不会像我们获取通用方法那样获取通用字段,因此方法类型推断将停止工作。

关于c# - 将成员委托(delegate)给经典函数有更多优点或缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8028059/

有关c# - 将成员委托(delegate)给经典函数有更多优点或缺点?的更多相关文章

  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-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

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

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

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

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

  6. 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

  7. 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中能不能做到类似的简洁?我可以只

  8. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

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

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

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

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

随机推荐