百科问答小站 logo
百科问答小站 font logo



C#的Delegate 为什么没在其他主流语言中普及? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

首先是delegate的设计其实是有一些历史问题的,并不能说是最好的一种设计。

一个典型的问题就在于所有的delegate实例都是MulticastDelegate类型的,但事实上多播委托的使用范围并没有那么大。更有意思的是多播委托本质上是个串行委托,委托方法是一个接一个的执行的。而实际应用场景中我们会遇到并发多播,异步多播,当某个出现错误时继续执行其他方法的多播委托,所有这些都是MulticastDelegate搞不定的。所以变得意义不大。

到今天为止MulticatsDelegate和+=的运算符重载还是多用于事件处理,而事件用默认的多播委托实现还会有可能导致对象不被释放的坑。



其次就是delegate这个概念意义并不大,尽管在强类型语言里面我们的确需要发明一种东西来描述函数签名,并将单个函数签名固化成一种强类型。但绝大多数时候专门去强调这个概念的意义并不大。很多语言都支持这个特性,但是一般可以直接用函数来描述就可以了,不必另外发明一个委托的概念。

另外就是传统的delegate强类型还有一个缺陷,即使两个delegate类型所代表的函数签名是一模一样的,那他们俩也是两个类型。这在实际运用中是个麻烦。如果你需要用到两个函数库,而这两个库分别将某个类型的函数签名定义了一个委托,即使你只需要写一个函数就能满足两个函数库的要求,但你仍然不得不莫名其妙的创建两个委托实例分别给到两个不同类型的委托对象。

这个缺陷直接催生了Func和Action系列的委托。

当Func和Action系列委托出现以及泛型委托类型参数的协变和逆变出现后,我们发现委托这个概念大部分时候变得很多余。

也就是说我们可以轻松地写出很多代码根本用不着了解委托这个概念,我们最终的着眼点还是函数签名。


但是别忘了泛型和匿名方法是C# 2.0才出现的(省略委托实例创建表达式直接用方法名称代替委托实例也是2.0才引入的),而泛型委托类型参数的协变和逆变是C#3.0才出现的,C#一直在发展的过程中。还有大家所说的lambda表达式也是3.0才引入的。


无论怎样,现在设计一个语言在语言内部保留委托的概念是很正常的,但是再花时间去把这个概念作为亮点来介绍,以及专门去学习和阐述是没有什么意义的。

即使是Java,其实那个SAM Type就是委托的别名,或者换句话说delegate就是SAM Type的别名和语法糖。


当然不管怎么样,C#的delegate语法相较于C/C++的函数指针的语法是一个巨大的飞越,而委托这种语法糖也远比所谓的SAM Type直观和简便



当然我也看到很多人说委托的学习成本太高,我想说其实OOP和强类型编程语言的学习成本本来就略高于平均智商水平,早日发现并作出正确的选择是非常对的。




  

相关话题

  你遇到过哪些代码优雅的C#项目? 
  c#中虽然异步和多线程是两码事,但是是否异步微软提供的async函数内部还是多线程去实现的? 
  Build 2018 开发者大会上发布的 .NET Core 3.0 规划蓝图透露了哪些信息? 
  有没有那么一次,Java让你欣喜若狂? 
  实际开发中ref、out参数有多大作用? 
  编译器是如何编译自己的? 
  Build 2018 开发者大会上发布的 .NET Core 3.0 规划蓝图透露了哪些信息? 
  有人号称编程零基础学C#4天,用记事本1分钟写个计算器,而且信誓旦旦,这是怎么回事? 
  C「带坏了」多少程序语言的设计? 
  C# 发明者与 Java 有关系么? 

前一个讨论
为什么 C++ 能够源码级兼容C语言?
下一个讨论
你是如何抵制百度系列产品的?





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利