为什么试图理解代表感觉就像试图理解宇宙的本质?

我读过两本书,一堆例子。 他们依然对我毫无意义。 我可以写一些使用代表的代码,但是我不知道为什么。 我是唯一有这个问题的人,还是我只是一个白痴? 如果有人能够向我解释什么时候,在哪里,为什么我会真正使用一个代表,我会永远爱你。

代表只是在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。 没有它,每个函数调用都必须在编译时进行修复。

涉及委托(或事件)的语法起初可能有点令人生畏,这有两个原因:

  1. 在C / C ++中简单的指针函数不会是types安全的,在.NET中,编译器实际上会生成一个类,然后尽可能地隐藏它。

  2. 代表是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没有任何关系,但是这不但值得一读,而且也值得一读。