stackoverflow上有人问,为什么不能把委托放在一个接口当中?

投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't gain anything by putting it inside the interface.”

翻译过来大致意思就是:委托只是一种类型,把委托放在接口中你什么也得不到。

看上去挺拗口的,如果你也感觉这句话说的不知所云,那么只能求助于MSDN的接口和委托的定义。

接口:只包含方法、属性、事件或索引器的签名。 实现接口的类或结构必须实现接口定义中指定的接口成员。

委托:是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 您可以通过委托实例调用方法。

似乎还不能让人满意,我们看到接口中可以包含事件,再想一想事件和委托之间的关系,想一想常见的Delegate、EventHandler、 Predicate、Func、Action…

为什么接口中可以有事件而不能包含委托?

你现在有没有陷入混乱而无语的恐慌当中?

换个角度从接口和委托的IL代码来看本质,其实说清楚为什么不能把delegate放在一个interface当中非常简单。

先看一个简单的接口定义:

ISampleInterface public interface ISampleInterface
{
/// <summary>
/// 方法
/// </summary>
void Say(string input); /// <summary>
/// 属性
/// </summary>
string Message { get; set; } /// <summary>
/// 索引器
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
string this[string input] { get; set; } /// <summary>
/// 事件
/// </summary>
event EventHandler<EventArgs> MyHandler; }

IL反汇编代码如下:

我们看到接口的定义中,方法、属性、索引器还有事件,本质上都是方法。其中索引器对应于get_Item,set_Item方法,属性对应get_Message,set_Message方法,而事件对应于add_MyHandler和remove_MyHandler方法。所以说属性、索引器还有事件只是语法糖而已。

我们再看下MSDN的委托示例:

public delegate int PerformCalculation(int x, int y);

它的反汇编代码如下:

根据IL,我们发现编译器自动将委托生成为一个继承自System.MulticastDelegate的类。

所以回头看委托的定义还是很有深刻意义的,委托只是一种定义方法签名的类型。而我们平时说自定义一个类型,通常就是自定义一个类,其实还应该包括自定义一个委托。

分析到这里,我们可以得出结论,接口内只能定义本质为方法的成员,不能定义类。

为什么不能把委托(delegate)放在一个接口(interface)当中?因为委托是一个类,而接口当中不能定义类。

参考:

http://stackoverflow.com/questions/612957/why-cant-i-put-a-delegate-in-an-interface

为什么不能把委托(delegate)放在一个接口(interface)当中?的更多相关文章

  1. C# 委托Delegate(一) 基础介绍&用法

    本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...

  2. java中的接口interface

    关于接口 接口描述了实现了它的类拥有什么功能.因为Java是强类型的,所以有些操作必须用接口去约束和标记.接口作为类的能力的证明,它表明了实现了接口的类能做什么. 类似与class,interface ...

  3. 【Java 基础篇】【第六课】接口interface

    Java提供的这个interface的语法,目的就是将接口从类中剥离出来,构成独立的主体. 首先加入我们定义了这个杯子接口: interface Cup { void addWater(int w); ...

  4. PHP面向对象程序设计之接口(interface)

    接口(interface)是抽象方法和静态常量定义的集合.接口是一种特殊的抽象类,这种抽象类中只包含抽象方法和静态常量. 为什么说接口是一种特殊的抽象类呢?如果一个抽象类里面的所有的方法都是抽象方法, ...

  5. Delegate(代理)异常:该委托必须有一个目标

    转自 Delegate(代理)异常:该委托必须有一个目标 在代理调用BeginInvoke(new AsyncCallback(callBack), null);时,会抛这个异常的原因是该代理变量代理 ...

  6. [C#] C# 知识回顾 - 委托 delegate

    C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...

  7. C# 代理/委托 Delegate

    本文转载自努力,努力,努力 1. 委托的定义:委托是函数的封装,它代表一"类"函数.他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数 ...

  8. 深入理解委托(Delegate)

    前言 委托其实一直以来都感觉自己应该挺熟悉的,直到最近又去翻了翻 CLR via C#,感觉我之前的理解可能还有失偏颇.在这记录一下. 之前文章的链接: 接口和委托的泛型可变性 C#高级编程笔记 De ...

  9. C# Note2:委托(delegate) & Lambda表达式 & 事件(event)

    前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...

随机推荐

  1. APK动态加载框架(DL)解析

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/39937639 (来自singwhatiwanna的csdn博客) 前言 好久 ...

  2. URL Quoting

    [URL Quoting] The URL quoting functions focus on taking program data and making it safe for use as U ...

  3. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。

    今天单位一ASP.NET网站,里面有个功能是导出数据,发现一导出就报错,报错内容是:SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT ...

  4. Visual Studio VS2010统计代码行数(转载)

    本文转自:http://blog.csdn.net/zhouworld16/article/details/9292851 在网上看到别人用的方法: 按CTRL+SHIFT+F (Find in fi ...

  5. (转载)selenium-webdriver(python)

    转载地址: http://www.cnblogs.com/fnng/p/3183777.html 本节重点: 简单对象的定位 -----自动化测试的核心 对象的定位应该是自动化测试的核心,要想操作一个 ...

  6. java核心知识点学习----重点学习线程池ThreadPool

    线程池是多线程学习中需要重点掌握的. 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互.在这种情形下,使用线程池可以很好的提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考 ...

  7. 转 SVN 在vs中的使用

    给大家介绍一些SVN的入门知识!希望对大家的学习起到作用!      关于SVN与CVS的相关知识,大家可以自己去google一下.      一.准备         SVN是一个开源的版本控制系统 ...

  8. redis Transaction支持

    前面主要介绍了redis数据类型,这里讲下事务问题 NoSQL都不支持事务,虽然Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC 提交执行的命令,在执行中服务器 ...

  9. Android之ImageView 旋转

    方案一: (1)获取ImageView对应的图片,并将其转成Bitmap; (2)创建Matrix对象; (3)调用matrix.setRotate(     );设置旋转度数 (4)重新创建bitm ...

  10. hdoj 2680 choose the best route

    Problem Description One day , Kiki wants to visit one of her friends. As she is liable to carsicknes ...