c#中委托的作用是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中委托的作用是啥?相关的知识,希望对你有一定的参考价值。

使用委托的作用:使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象,而且是类型安全的。

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

委托和事件在.NET Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。

扩展资料:

委托的本质:

在C#中使用delegate关键字定义委托,然后使用我们熟悉的函数调用的语法来调用委托,如上述例子中的cb(“skynet”,23)。在这简单的表象背后,.NET编译器可以知道定义CallBack委托时,编译器为我们做了如下工作,实际上定义任何委托编译器都会做如下工作:

声明一个类,对应上图中的.class nested public auto ansi sealed。该类扩展自System.MulticastDelegate,对应上图中的extends [mscorlib]System.MulticastDelegate。

该类包含一个构造器,对应上图中的.ctor: void(object ,native int)。该类包含三个方法,分别是BeginInvoke、EndInvoke、Invoke。

参考资料来源:百度百科-委托 (C#类)

参考资料来源:百度百科-c#委托

参考技术A c#用委托来实现事件通知机制。委托相当与c++函数指针。整个过程涉及一个呼叫者,一个被呼叫者,还有就是这个委托。

- 实现步骤
有以下几步: 1. 申明委托, 2.定义呼叫者和调用的函数, 3.定义被呼叫者和具体实现的函数(被调用的函数)

1.申明委托 ,在包里或者类里,public
public delegate void PlayGame(Object sender, EventArgs e);
2.定义呼叫者(类LetsGame)和调用委托的函数,在呼叫者里要有委托的实例(呼叫者扔出一个委托,被呼叫者给这个委托赋值)
class LetsGame
public event PlayGame theGame;
public void startPlay(EventArgs e)
if(theGame != null)
theGame(this,e);



3. 定义被呼叫者(类MS)和具体实现的函数(被调用的函数),也就是concrete class的实现或者叫函数指针实例。打个比方,在一个叫MS的类中实现.MS中对呼叫者中委托的实例进行赋值.
class MS
public MS(LetsGame lg)
lg.theGame += new PlayGame(MSPlayGame);

public void MSPlayGame(Object sender, EventArgs e)
Console.WriteLine("Who laughs the last who wins");



这样当调用LetsGame.startPlay的时候就会调用MS.MSPlayGame.

- 实际应用
对照一下c#的GUI事件处理或者asp.net的web控件事件处理,能帮我们更好的理解委托和事件.大家一定很熟悉asp.net里下面的代码
private void InitializeComponent()


this.Button1.Click += new System.EventHandler(this.Button1_Click);



private void Button1_Click(object sender, System.EventArgs e)

//do sth


这就是用委托来实现事件.你可能发现我们并没有给它声明委托对象并通过event关键字来引用该委托对象,那是因为asp.net早就帮我们做好了该项工作,其委托对象是System.EventHandler. Button1相当于上面的LetsGame的实例,是呼叫者,Button1_Click是被呼叫方法.当你click Button1后,Button1就会调用Button1_Click.

-杂项
我觉得这种机制和design pattern里的observer很类似,我们完全可以用observer来达到同样的效果,但是用委托更灵活,不需要定义一个interface然后所有的concrete class都实现某个方法,函数指针(委托)更灵活.

还有,委托不一定非要和事件一起用,单独用的时候就是函数指针.
参考技术B 其实很简单啦,就是用来传方法的。
平常我们的方法或者函数只能用来传参数,有的时候一个方法可能需要另一个方法的支持,所以我们可以定义个委托来传这个方法。
需要注意的是,委托和你所要传的方法的返回值类型要一致。
参考技术C 传值

表中委托的 Qt 事件

【中文标题】表中委托的 Qt 事件【英文标题】:Qt event for delegate in table 【发布时间】:2015-05-07 13:45:27 【问题描述】:

问题/问题

我尝试在自定义委托中重新实现 event 方法来处理点击。委托用于在表格视图中呈现表格单元格。但是,我没有得到委托的任何事件(根据调试器永远不会调用该方法)。我需要做些什么特别的事情才能让我的代表跟踪事件(特别是鼠标进入/退出、点击)?

上下文

我想为表格单元格创建自己的数据表示。功能应该接近按钮,但略有不同。我读到在表格中实现按钮的两个选项是设置一个据称具有很高性能成本的单元格小部件(我不太明白为什么)或使用委托。

因为我想要与按钮不同的行为,并且为了速度神话,我决定使用代表。

【问题讨论】:

如果您需要处理鼠标点击,请处理实际发生事件的对象的信号/事件。如果您的委托类为单元格表示提供小部件,请在该小部件上而不是在委托类中处理事件。 @vahancho 我的代表只是用QPainter.drawPixmap 绘制了一个QPixmap,我想没有什么可以吃掉这些事件。问题是,我是否需要以某种方式为我的委托启用事件,或者有什么理由让委托不应该接收事件? 如果您的委托只是用于绘画,那么您可以使用表格视图的QAbstractItemView::clicked() 信号来处理鼠标点击。根本不需要处理事件。 我只是继承QAbstractItemDelegate,实际上我想处理鼠标向下/向上和鼠标悬停/鼠标移出事件。此外,即使事实证明有 buttonDown/upmouseEnter/leave 方法,我仍然想弄清楚为什么我的 event 函数根本没有被调用。 QAbstractItemDelegateQObject。它不能接受和处理 GUI 事件。再次 - 在基于 QWidget 的类中处理 GUI 事件,例如,您的表格视图。 【参考方案1】:

鼠标事件被发送到QAbstractItemDelegate::editorEvent() 方法,即使它们没有开始编辑项目。

见:http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent

【讨论】:

以上是关于c#中委托的作用是啥?的主要内容,如果未能解决你的问题,请参考以下文章

细说委托

深入理解委托——为什么C#要引入委托

kotlin中委托的概念和原理

XCode(iOS)中委托的自动导入回调

.Net中委托的协变和逆变详解

C#中代表DELEGATE的作用是啥