怎么理解委托?

测试出生的码农 2019-07-05 01:23:54
比如:在Winform开发中,因为涉及到跨线程操作,所以后台需要使用委托来更新界面数据。
问题:
1. 为什么委托可以实现两个线程之间的数据传递?
2. 到底委托给了谁去进行相关操作的?
3. 委托其实用的地方很多,比如Lambda表达式就属于一种匿名委托。所以一般哪些地方会用到委托?
...全文
3489 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
palhotel 2019-07-09
  • 打赏
  • 举报
回复
现在都有Lamda表达式了,委托的概念也不用很关心了。因为一开始C#学JAVA,但JAVA没有传函数,或者函数式的概念,写回调函数还需要弄个接口,再弄个匿名内部类,特别麻烦。C#不能全学JAVA,就要有改进,用委托就会方便点。后来C#和JAVA都有了更多函数式编程的概念,都支持lamda了,也就不太重要了。
绿色盒子 2019-07-08
  • 打赏
  • 举报
回复
委托就是给一类结构相似的函数声明一个类型,让它可以作为函数参数调用,在一定程度上和C++中的回调函数有异曲同工之妙
秋的红果实 2019-07-08
  • 打赏
  • 举报
回复
我的理解: int x;x可以存放1000,100000等 public delegate int Del(bool b);Del可以存放方法
qq_29817615 2019-07-07
  • 打赏
  • 举报
回复
委托两层含义: 函数指针 和 封装 , 函数指针 是4或者8个字节的变量 ,这个变量 和 系统api的函数指针通用,
封装 是c# 在代码里面 封装好了的 , 即 结构体或者类的成员函数 ,在委托函数 里面都封装了对应的对象
winform 界面更新 需要委托, winform 循环中 维护了 委托集合 , 当调用invoke 的时候 像这个委托集合添加委托,
当winform循环 发现委托集合 有成员,就执行成员的方法,这样 委托和winform循环 就是一个线程上运行的了
lindexi_gd 2019-07-07
  • 打赏
  • 举报
回复


C# 委托 https://blog.lindexi.com/post/C-%E5%A7%94%E6%89%98.html
大鱼> 2019-07-07
  • 打赏
  • 举报
回复
引用 28 楼 wanghui0380 的回复:
为啥你们一定要往线程上拽????????拉都拉不回。非要说线程就高大上了? 请问,linq的where有线程么? 请问,js的闭包有线程? 请问,c++的回调函数有线程??? 如果一定要高大上才能显示出NB,知识丰富。行,没问题。都要高大上是吧,那我说说高大上的“函数式编程”-------F#一切皆委托多NB,多高大上
稳住发育,不要浪
wanghui0380 2019-07-07
  • 打赏
  • 举报
回复
为啥你们一定要往线程上拽????????拉都拉不回。非要说线程就高大上了? 请问,linq的where有线程么? 请问,js的闭包有线程? 请问,c++的回调函数有线程??? 如果一定要高大上才能显示出NB,知识丰富。行,没问题。都要高大上是吧,那我说说高大上的“函数式编程”-------F#一切皆委托多NB,多高大上
张天星 2019-07-06
  • 打赏
  • 举报
回复
中文还是很靠谱的,委托这个词,就是字面意思,上面一层层的也说的很清楚了。 楼主还迷糊的话,去百度找找各种委托demo,不仅仅是看,用代码去调试,断点,一步步运行,应该会更好理解。
  • 打赏
  • 举报
回复
要理解委托,参考《CLR via C#》。 其他线程要更新UI线程创建的控件的内容,就必须告诉UI线程:你给我执行“更新操作”,即UI线程调用给定的函数,而这个函数是由这个“其他线程”指定的。如果你有SendMessage和PostMessage的知识,会有助于理解的。 另外UI线程创建的控件对象只能由该线程自己才操作。最好就是这样使用,不要去移除这个限制。
threenewbee 2019-07-05
  • 打赏
  • 举报
回复
简单来说。就是把一个函数作为一个变量,这就是委托。把函数传给别的函数,让它们来调用。

比如说定义了一个函数
void foo() { ... }
我们程序里调用它
foo();

但是现在我们需要如下的操作
void func(int type) {
if (type == 1)
foo1();
else if (type == 2)
foo2();
else if (type == 3)
foo3();
}
也就是说不同情况需要调用不同的foo1 foo2 foo3
问题是,这么写,总是要求func这个函数知道要调用的函数的名字,它不能调用一个对于它来说,陌生的函数。
我们就需要把这个函数名作为一个“变量”,那么这个时候就是用委托。
void func(Action act) {
act();
}

这么写就不同了。
此时,作为调用者可以把任意没有参数没有返回值的函数作为参数变量给func,而func可以调用它的编写者不认识的任何函数。
比如
调用者编写
void foo100() { ... }
调用func:
func(foo100);

那么foo100一样就可以被func来调用。

因为foo100是调用者后编写的,而func是被调用者,先写好的。
所以等于func这个函数中的一部分代码就可以由调用者来定义,实现了对功能的自定义。

委托不是用来解决跨线程数据传输的,它解决的是,将一个操作从一个线程移到另一个线程去做。或者说跨线程代码的传输。如果是数据的传输,直接用全局变量同步下就可以。

之所以要把一个操作从一个线程移到另一个线程去做,这是因为只有UI线程(主线程),操作界面才是安全的。所以操作界面的代码必须由主线程来执行。

前面说了,委托就是把函数(代码)像变量一样传给另一个函数的参数/对象,因此就可以让另一个函数/对象来执行这些代码。
ljg3081022a 2019-07-05
  • 打赏
  • 举报
回复
委托用来约束 事件基于委托
wanghui0380 2019-07-05
  • 打赏
  • 举报
回复
比如说这个“测试出生的码农”---你的名字 如果说测试这件事,作为正常抽象逻辑是 do编写代码(); if(自测()) { 测试委托?(代码) //对啊,我们委托给专业测试去测试,如果专业测试存在的话 发布程序 }
wanghui0380 2019-07-05
  • 打赏
  • 举报
回复
技巧技术取决你想干啥 所以是思路上那样,然后有时被技术限制,迫不得已做的技术。 so,新人不要走偏,一开始就非要去追技术。去神秘兮兮的,去讨论什么跨线程这类,讨论lock多么多么高级。语法写法不重要,你的想明白这么写的道理,而是这么写机器上的技术。 这里根本就没啥跨线程,只是一个单纯的委托,只是因为技术上你没有那个权限去做,所以迫不得已这么写而已。这不是什么高级技术,也不是什么非常NX的东西,这是受制与技术的无奈选择(类比一下:7年前苹果在美国卖100,200美元,这里6k。怎么办,委托给国外黄牛代买,委托给国外黄牛代解锁--当时解锁是需要报美国社保号的,这样的操作你觉着有技术,就是跨国交易?没技术啊,只是无奈的选择而已) 至于委托,还就是委托,没啥解释的 比如不说最新的,就拿最远古的net一出来就有的Array.Sort 好,我排个序可以把,微软写这个代码的知道,明白。这么快排,这么堆排。 但是,这么比大小你知道么?不知道,int,string知道,但是我说,这样吧,给你一群美女照片,你按颜值给我排 微软大大说,额,颜值是啥?所以他Sort 给你个委托,委托你来告诉我颜值是啥,我只管排序,不管颜值,所以你看到了他给你个规定 A,B 给我个int的委托,你自己比较A和B谁颜值高,给返回-1就是A比B丑,1就是A比B美,0就是A和B差不多。 行了我写Array.Sort 算法上的排序就是了,你写你的A,B比较美丑的委托实现就成 这就是委托最本质的意思,我们抽象可以抽象的,那些需要外面操作的交给外面操作。不然怎么样,难道让微软的人等你把比较美丑的东西实现了,微软在给你写Array.sort??那到现在微软都做不出这个net框架,天知道你们到底要做啥
正怒月神 2019-07-05
  • 打赏
  • 举报
回复
引用 11 楼 weixin_45364561 的回复:
我是一名初学者,我觉得懂的人讲到委托,其他懂的人觉得也是这么一回事。 问题来了,他们是不会理解到初学者的困惑的。我这样说,一个成人面对小学的知识点,难吗?不难吧,可是让你去教一个小学生,你觉得你能比小学老师胜任吗?你在网上看到那些暴躁家长了吗? 所以,怎么通俗地让初学者掌握这一技能?张子阳的博客是全网委托最先阅读量最大的了,我也一样还是觉得似懂非懂。尤其是委托的继篇 我是觉得能不能让初学者不要尝试去理解delegate,直接用现成的Action或Func。等他们回过神后再去理解delegate不是更好吗? 请问现实中有多少个项目需要到程序员用delegate而不是用Action或Func?
这个是由于现在有更优化的语法糖来支持,因此你可以使用action 和func来代替delegate。 就像在没有 async await时,异步就要回调函数。 现在却可以书写类似于同步编程的方式来实现异步。 所以回过头来,明白委托,就是明白了。 不明白委托。就是不明白的。 我个人认为,这是概念上要明白,而不是形式上要明白。 就好像java说,我自己是没有委托的。结果他有事件监听。
  • 打赏
  • 举报
回复
我是一名初学者,我觉得懂的人讲到委托,其他懂的人觉得也是这么一回事。

问题来了,他们是不会理解到初学者的困惑的。我这样说,一个成人面对小学的知识点,难吗?不难吧,可是让你去教一个小学生,你觉得你能比小学老师胜任吗?你在网上看到那些暴躁家长了吗?

所以,怎么通俗地让初学者掌握这一技能?张子阳的博客是全网委托最先阅读量最大的了,我也一样还是觉得似懂非懂。尤其是委托的继篇

我是觉得能不能让初学者不要尝试去理解delegate,直接用现成的Action或Func。等他们回过神后再去理解delegate不是更好吗?

请问现实中有多少个项目需要到程序员用delegate而不是用Action或Func?
OrdinaryCoder 2019-07-05
  • 打赏
  • 举报
回复
你提到委托在让界面现场操作界面控件时使用 ,为什么要这样呢 因为只有界面线程可以操作控件
而委托在这里怎么理解呢 我觉得可以理解为 你告诉界面线程 我想要让这个控件怎么样 然后界面线程知道了 等到有时间的时候 界面线程就把这件事干了 这里干这件事的是界面线程 而不是你启动的工作线程
  • 打赏
  • 举报
回复
引用 6 楼 wanghui0380 的回复:
所以你压根别纠结

我要买房,我有钱。
我委托给中介帮我看着

我要卖房,没时间。我委托给中介帮我看着

我买了房,我不会装修。委托给装修公司

-------------------------------




买房(func<钱,房> xxx)
{
房 _房= xxx?.(钱)
}

就这么简单的一件事情,搞那么复杂干嘛?

这不是还没搞清楚,正在搞清楚嘛
你是在理解的基础上,觉得很简单。我就是还没打通这一关,正在摸索。
exception92 2019-07-05
  • 打赏
  • 举报
回复
因为涉及到跨线程操作,所以后台需要使用委托来更新界面数据。 -》并不是委托,而是将执行代码封送到UI线程中,这个切换由TaskScheduler执行,封送的方式可以通过委托。 1. 为什么委托可以实现两个线程之间的数据传递? -》因为在不同的线程,委托是方法的另一个种表示,不过委托可以进行异步执行。 2. 到底委托给了谁去进行相关操作的? -》没有谁,比如更新界面就是UI线程。 3. 委托其实用的地方很多,比如Lambda表达式就属于一种匿名委托。所以一般哪些地方会用到委托? -》自定义event/上边的跨线程/基于Task的多线程/支持回调函数的类 ps:个人观点,不喜勿喷。
wanghui0380 2019-07-05
  • 打赏
  • 举报
回复
所以你压根别纠结 我要买房,我有钱。 我委托给中介帮我看着 我要卖房,没时间。我委托给中介帮我看着 我买了房,我不会装修。委托给装修公司 ------------------------------- 买房(func<钱,房> xxx) { 房 _房= xxx?.(钱) } 就这么简单的一件事情,搞那么复杂干嘛?
wanghui0380 2019-07-05
  • 打赏
  • 举报
回复
委托就是委托,没啥跨线程的意思。本来就是委托给别人,跨不线程都是委托。 谁回答你这个委托,你就委托给了谁。 你中文里委托怎么用,你代码里委托就怎么用 我委托你代购 我发个帖子委托别人给我写个demo,谁愿意接着活就委托给了谁。没人接?也正常,委托是null就是null呗。 俺们起个合同正式委托给你,或者俺们就口头约定就按这个办(匿名委托) so----------不知道你在纠结啥,委托就是委托。还不明白,请查新华字典
加载更多回复(4)

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧