为什么试图理解代表感觉就像试图理解宇宙的本质?
我读过两本书,一堆例子。 他们依然对我毫无意义。 我可以写一些使用代表的代码,但是我不知道为什么。 我是唯一有这个问题的人,还是我只是一个白痴? 如果有人能够向我解释什么时候,在哪里,为什么我会真正使用一个代表,我会永远爱你。
代表只是在variables中传递函数的一种方式。
你传递一个委托函数来做callback。 例如,在执行asynchronousIO时,您传递一个委托函数(您用委托参数编写的函数),当数据从磁盘读取时将被调用。
正如其他人所提到的,代表们可以方便地进行callback。 它们对于其他东西也是有用的。 例如,在我最近研究过的一个游戏中,子弹击中时会做不同的事情(有的会造成伤害,有的会增加被击中的人的身体健康,有的则不会造成伤害,而是毒害目标等等)。 传统的面向对象的方法是基础子弹类和子类的加载
Bullet DamageBullet HealBullet PoisonBullet DoSomethingElseBullet PoisonAndThenHealBullet FooAndBarBullet ....
有了这个模式,每次我想要一个新的行为在子弹中,我必须定义一个新的子类,这是一个混乱,并导致了很多重复的代码。 相反,我解决了与代表。 子弹有一个OnHit委托,当子弹击中一个对象时被调用,当然,我可以让这个委托给我喜欢的任何东西。 所以现在我可以像这样创build子弹
new Bullet(DamageDelegate)
这显然是一个更好的做事方式。
在function语言中,你往往会看到更多的这种东西。
委托是一个简单的容器,它知道特定方法所在的机器内存的哪个位置。
所有代表都有一个Invoke(...)
方法,因此当某个人有一个委托时,他可以真正执行它,而不必知道或困扰该方法实际执行的操作。
这对解耦的东西特别有用。 没有这个概念,GUI框架是不可能的,因为一个Button
根本无法知道你要使用它的程序的任何内容,所以无论何时它被点击,它都不能调用你的方法。 相反,你必须告诉它在点击时应该调用哪些方法。
我想你对事件很熟悉,你经常使用它们。 event
字段实际上是这样的代表(也称为多代表委托)的列表。 也许事情会变得更清晰,当我们看看如何在C#中“模拟”事件,如果它没有event
关键字,但只有(非多播)委托:
public class Button : Rectangle { private List<Delegate> _delegatesToNotifyForClick = new List<Delegate>(); public void PleaseNotifyMeWhenClicked(Delegate d) { this._delegatesToNotifyForClick.Add(d); } // ... protected void GuiEngineToldMeSomeoneClickedMouseButtonInsideOfMyRectangle() { foreach (Delegate d in this._delegatesToNotifyForClick) { d.Invoke(this, this._someArgument); } } } // Then use that button in your form public class MyForm : Form { public MyForm() { Button myButton = new Button(); myButton.PleaseNotifyMeWhenClicked(new Delegate(this.ShowMessage)); } private void ShowMessage() { MessageBox.Show("I know that the button was clicked! :))))"); } }
希望我能帮一点点。 😉
Chris Sells撰写的这篇文章可能有所帮助:
.NET代表:AC#睡前故事
也许这有助于:
- 委托是一种types(定义方法签名)
- 委托实例是对方法的引用(AKA函数指针)
- callback是委托types的参数
- 事件是委托types的(种)属性
代表的目的是你可以拥有“持有”一个函数的variables/字段/参数/属性(事件)。 这使您可以存储/传递select运行时的特定function。 没有它,每个函数调用都必须在编译时进行修复。
涉及委托(或事件)的语法起初可能有点令人生畏,这有两个原因:
-
在C / C ++中简单的指针函数不会是types安全的,在.NET中,编译器实际上会生成一个类,然后尽可能地隐藏它。
-
代表是LINQ的基石,从C#1到匿名方法(C#2)到lambda(C#3)的所有指定都有了一个陡峭的演变。
只要熟悉1或2个标准模式。
拜托了伙计们! 你们所有人都成功复杂的代表:)!
我将尝试在这里留下一个提示:我了解委托,一旦我意识到jquery调用JavaScript的Ajax。 例如:ajax.send(url,data,successcallback,failcallback)是函数的签名。 如你所知,它发送数据到服务器的URL,作为响应,可能是200OK或其他错误。 如果发生这种事件(成功/失败),则需要执行一个function。 所以,这就像一个函数的占位符,能够提及成功或失败。 该占位符可能不是非常通用的 – 它可能接受一组参数,并且可能不会返回值。 这个占位符的声明,如果在C#中完成,叫做DELEGATE! 由于JavaScript函数对参数数量不严格,所以您只能将它们看作GENERIC占位符…但是C#有一些STRICT声明…归结为DELEGATE声明!
希望能帮助到你!
Delegate是一个types安全的函数指针 ,意思是当你调用委托函数时, 委托指向一个 函数 , 实际的函数将被调用 。 它主要用于开发核心应用程序框架。 当我们想要分离逻辑,那么我们可以使用委托。 也就是说,而不是在一个特定的方法手工编码逻辑,我们可以将委托传递给函数,并在委托函数内部设置不同的function逻辑 。 代表增加了框架的灵活性。
例如:如何使用它
class program { public static void Main) { List<Employee> empList = new List<Employee> () { new Employee () {Name = "Test1", Experience = 6 }, new Employee () {Name = "Test2", Experience = 2 }, } // delegate point to the actual function IsPromotable isEligibleToPromote = new IsPromotable(IsEligibleToPromoteEmployee) Employee emp = new Employee(); // pass the delegate to a method where the delegate will be invoked. emp.PromoteEmployee(empList, isEligibleToPromote); // same can be achieved using lambda empression no need to declare delegate emp.PromoteEmployee (empList, emply =>emply.Experience > 2); // this condition can change at calling end public static bool IsEligibleToPromoteEmployee (emp){ if (emp.Experience > 5) return true; else return false; } } } public delegate bool IsPromotable(Employee emp); public class Employee { public string Name {get; set;} public int Experience {get; set;} // conditions changes it can 5, 6 years to promote public void PromoteEmployee (List<Employee> employees, IsPromotable isEligibleToPromote) { foreach (var employee in employees) { // invoke actual function if (isEligibleToPromote(employee)){ Console.WriteLine("Promoted"); } } }
我不认为有人提到过,但Jon Skeet在他的书“ 深度C# ”中的代表部分可能是我见过的最好的。 就像OP一样,我曾经和代表们斗争过。 我曾经遇到的问题是设立代表。
Jon Skeet的书很好地解释了代表,因为它破坏了委托“设置”,在委托types和委托实例之间做出了澄清(您必须亲自动手才能理解这本书,否则我可能会打开我自己的版权侵犯,因为我不能比Jon更好地解释它)。 最重要的是他提供了一个小而清晰的例子。
我与Jon Skeet或Manning没有任何关系,但是这不但值得一读,而且也值得一读。