Difference between events and delegates and its respective applications
我想知道代表们的目的是什么。我没有那么多地使用它们,也不能真正想到什么。
在我的课程中,写的是代表是符合其签名的所有方法的蓝图。
此外,您可以向一个委托添加多个方法,然后按照添加顺序在彼此之后执行它们。这可能仅对影响局部变量的方法或不返回任何值的方法有用。
我已经读过C#将Events实现为委托,记录为:
//Summary: Represents the method that
will handle an event that has no event
data.
//Parameters:
//sender: The source of the event.
//e: An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
不过,这有点令人困惑。有人可以给出这个概念的一个好的,有用的例子吗?
答案 0 :(得分:26)
是的,
你快到了。委托是指要调用的方法或函数。 .NET使用事件说..当有人按下这个按钮时,我希望你执行这段代码。
例如,在使用GPS应用程序时:
public delegate void PositionReceivedEventHandler(double latitude, double longitude);
这表示该方法必须将两个双精度作为输入,并返回void。当我们定义一个事件时:
public event PositionReceivedEventHandler PositionReceived;
这意味着PositionRecieved事件调用的方法与定义相同 我们定义的PositionReceivedEventHandler委托。所以当你这样做时
PositionRecieved += new PositionReceivedEventHandler(method_Name);
method_Name必须与委托匹配,以便我们知道如何执行该方法,以及它所期望的参数。例如,如果使用Visual Studio设计器将某些事件添加到按钮,则它将在期望对象和EventArgs参数的委托上工作。
希望有所帮助...
答案 1 :(得分:14)
正如您所指出的,委托是一种为方法调用创建签名的方法。有许多使用委托的很好的例子,但真正让我开心的就是这个例子。
public delegate Duck GetDuckDelegate();
public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type)
{
switch(type)
{
case "Rubber":
return new GetDuckDelegate(CreateRubberDuck);
case "Mallard":
return new GetDuckDelegate(CreateMallardDuck);
default:
return new GetDuckDelegate(CreateDefaultDuck);
}
}
public Duck CreateRubberDuck()
{
return new RubberDuck();
}
public Duck CreateMallardDuck()
{
return new MallardDuck();
}
public Duck CreateDefaultDuck()
{
return new Duck();
}
然后使用它
public static void Main() {
var getDuck = GiveMeTheDuckFactoryMethod("Rubber");
var duck = getDuck();
}
可以说,工厂模式对于这个来说是一个更好的方法,但我只是想起了这个例子,并认为它证明了委托如何被视为对象的重点
答案 2 :(得分:3)
委托允许您传递类似值的方法。
例如,.Net有一个名为Array.ForEach
的方法,它接受一个委托和一个数组,并在数组的每个元素上调用委托。
因此,你可以写,
int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 };
Array.ForEach(arr, new Action<int>(Console.WriteLine));
此代码将为数组中的每个数字调用Console.WriteLine
。
通过创建接受委托的函数,您可以做很多事情,尤其是在与匿名方法结合使用时。例如,请查看LINQ。
答案 3 :(得分:2)
我可以使用Web应用程序架构为您提供示例:
通常,使用Web应用程序,您可以提供接收来自许多客户端的请求的前端控制器。我们可以将所有方法放在前端控制器中,以处理来自客户端的许多不同类型的请求。但是,这有点麻烦。相反,我们可以使用委托来封装不同请求的功能。我们可以:
等等。因此,将功能分解为逻辑块是一种巧妙的方式 - 代表。 Struts框架基于这种工作方式(ActionServlet和Action类)。
答案 4 :(得分:2)
有许多优秀的文章解释代表 - 这里有一些好的:
答案 5 :(得分:2)
许多人最初对代表和事件的真正需求感到困惑。我是其中之一,我花了一些时间才弄明白:-)。最近在ASP.NET论坛中回答了一个类似的查询,并认为如果我在这个主题上创建博客文章会更好!这是查询:
“我正在读一个银行类别的某个例子,如果达到最低余额,你需要通知应用程序的其余部分已达到最小值,但我们不能通过调用普通方法来做到这一点。 例如:让我们说当我们从余额中扣除一些金额时,如果达到最小值然后调用一些方法来采取一些行动,我完全不知道为什么我们需要代表和自定义事件?“
事情就是在银行的情况下,你绝对可以调用一个方法,但那时它将是简单的程序编程,当我们希望我们的代码响应系统生成的某些事件时,我们需要基于事件的编程。
例如:认为Windows OS是一个系统,我们正在编写一个代码(用任何语言)来捕获像mouse_click()这样的事件。现在我们的程序如何知道鼠标点击发生了?我们可以使用低级代码,但由于操作系统已经在处理低级代码,因此最好捕获操作系统引发的事件。
换句话说,当mouse_click()发生时,OS会触发一个事件。操作系统并不关心谁捕获此事件并使用它,它只是发出通知。然后任何代码(如我们的)都可以捕获该事件并相应地使用它。这为我们自己编写代码节省了大量时间。其他程序也可以使用相同的事件并相应地处理它。
同样,银行系统可能很庞大,许多其他外部应用程序可能正在访问它。银行系统不知道有多少这样的应用程序需要它,或者依赖于它,以及它们如何处理某些情况,例如当余额很低时,所以它只是在低余额发生时触发事件,这个事件可以除了银行代码本身之外,还可以被任何其他代码使用。
请注意,该事件的每个susbcriber都可以独立处理该事件,例如。如果余额不足,银行代码可能会停止执行某些操作,某些其他报告应用可能会在这种情况下发送电子邮件,或者某些ATM代码可以停止特定交易并通知用户余额很低。
希望这会让事情变得清晰!
答案 6 :(得分:1)
根据我的理解,代表提供了一种专门化类行为的方法,而无需对其进行子类化。
某些类具有复杂的通用行为,但仍然需要专门化。想想GUI框架中的一个Window类:一个Window可以自己做很多事情,但你很可能仍然希望以某种方式专门化它。在某些框架中,这是通过继承完成的。这样做的另一种方式是代表。假设您希望在Window调整大小时发生某些事情:您的委托类可以实现一个名为onWindowResize的方法(当然,前提是Window类支持此方法),只要Window调整大小就会调用它,并且当窗口负责任何特殊行为时调整大小。
我不会主张代表团对继承的优点,但足以说有许多人认为代表团比继承更“干净”。