C# 为什么以及何时使用事件?

C# 为什么以及何时使用事件?,c#,.net,events,C#,.net,Events,在我的个人项目中,我从未使用过事件。我从未觉得有必要使用事件。尤其是使用事件会产生一些问题,比如对具有相同参数的方法的限制,这就是为什么我没有使用它的原因。使用它有什么好处?我们何时何地需要它 编辑:使用事件更适合于封闭源代码库?因为我们不能将任何方法附加到现有的封闭源代码方法,所以事件可以帮助我们解决这个问题吗?因为在开源中,我们可以很容易地将方法添加到方法的末尾。当您需要观察者对对象中发生的事件做出反应时:) 最明显的例子是UI组件—例如,按钮公开一个事件,该事件在单击按钮时触发 如果你没有

在我的个人项目中,我从未使用过事件。我从未觉得有必要使用事件。尤其是使用事件会产生一些问题,比如对具有相同参数的方法的限制,这就是为什么我没有使用它的原因。使用它有什么好处?我们何时何地需要它


编辑:使用事件更适合于封闭源代码库?因为我们不能将任何方法附加到现有的封闭源代码方法,所以事件可以帮助我们解决这个问题吗?因为在开源中,我们可以很容易地将方法添加到方法的末尾。

当您需要观察者对对象中发生的事件做出反应时:)

最明显的例子是UI组件—例如,
按钮
公开一个事件,该事件在单击按钮时触发


如果你没有任何自然感觉像是暴露事件的东西,那么不使用它们也没关系。但是,如果你有任何其他方面对你的对象发生的事情感兴趣的东西,你应该考虑事件和/或框架。

< P>你不需要使用它。然而,如果你正在解决的问题需要它,它只是你最终将要做什么的捷径。但是,由于您使用的是C#.NET,它有一个快捷方式,因此您最好使用它们。当服务器可以调用客户机的方法时,事件用于回调。这种选项不仅存在于c#(c++中的f.e.函数指针)中。当然,您可能不会使用事件构建代码来避免它们。我建议更好地了解它们并了解它们的优点。

最明显的例子是,事件在处理GUI时特别有用。应用程序用户通常与代码的前端部分(本例中为图形界面)交互,而大多数逻辑是“隐藏”的

我相信你已经看到了这个模式——你按下按钮,背景中发生了一些事情,你会看到操作结果。您不需要知道到底发生了什么,您只对应用程序窗口中显示的字符串感兴趣,该字符串表示“您的机票已预订”

用户界面也是如此。在大多数情况下,它不需要知道(也不应该知道)应用程序逻辑是如何实现的,或者它是做什么的。它用于展示结果并与用户交互

在.NET中是如何工作的?考虑机票预订示例的延续,部分代码<代码> TigkBookk./Cuff>类:

public event Action BookingSuccessful;

public void BookTicket()
{
    // lot of complex steps that should run in background
    this.ValidateInputData();
    this.GetTicketInfo();
    this.CheckUserInfo();
    this.SendDataToOperator();
    this.WithdrawMoney(); 
    // ...and perhaps lot more stuff you might want to do 
    // in order to book ticket
    if (booked)
    {
        // we're done: let's raise event which will 
        // notify all interested observers 
        this.BookingSuccessful();
    }
}
正如您所看到的,
BookTicket
方法可能需要很长时间才能完成,可能有许多复杂的步骤,其中的大部分——作为一个用户——我们不想知道。无论我们是否预订,我们只需要这些信息

知道了这一点,我们不希望用户等待挂起的应用程序,因为正在预订机票。用户仍然应该能够与它进行交互(当然在某种程度上)。因此,用户界面类想要订阅
TicketBooker
class事件

TicketBooker tb = new TicketBooker();
tb.BookingSuccessful += this.ShowSuccessMessage;

// ... somewhere here we call tb.BookTicket() method to run in background
// once it completes (with success), it will raise BookingSuccessful event
// which will cause ShowSuccessMessage to execute, as we subscribed it

public void ShowSuccessMessage()
{
    // simply display success message in interface, eg. by setting label text
}
整个画面当然比这个简单的例子要大得多。事件有助于将应用程序表示层与数据模型/业务逻辑分离,它们处理有关对象更改的感兴趣对象通知等

对于初学者,您可以在MSDN上查看本教程:

检查模型-视图-控制器模式的工作方式也可以更好地理解:


和往常一样,关于这个主题的资源非常丰富,只需搜索标记的问题。

哦,我也有同样的问题。我理解事件的概念,因为我在JavaScript中大量使用它们,但我无法证明在C#应用程序中使用事件是合理的。我的意思是,我使用了server
OnClick
等,但我不明白为什么要在其他地方使用事件

事实上,这是一个有趣的故事,因为我在制作ORPG游戏时,通过艰苦的努力才学会了这一点。考虑下面的代码:

class Player
{
    private int health;
    public int Health
    {
        get
        {
            if (health <= 0)
            {
                Die();
            }

            return health;

        }

        set
        {
            health = value;
        }
    }

    public void Die()
    {
        // OMG I DIED, Call bunch of other methods:
        // RemoveFromMap();
        // DropEquipment(); etc
    }
}
现在,当我创建新播放器时,我可以将任何方法分配给它的
DieHandler

Player player = new Player("Joe");
player.Die += Client.Players.PlayerDie;

Player npc = new Player("Cookie Monster");
npc.Die += Client.Npcs.NpcDie;
其中,
Client.Npcs.Die
Client.Players.Die
是以下内容之一:

public void NpcDie(Player sender, EventArgs e)
{
    //who hoo, I can be implemented differently
    //I can even check if sender.Health <= 0
}

public void PlayerDie(Player sender, EventArgs e)
{
}
public void NpcDie(玩家发送者,事件参数e)
{
//谁呼,我可以用不同的方式实现

//我甚至可以检查sender.Health是否响应良好,但在本例中,您是否有效地使用事件来避免对玩家进行子分类?在我的实际代码中,玩家和Npc都继承自Gamebeeng。服务器客户端示例更好,因为我必须根据使用该类的位置对Player/Npc对象执行不同的操作。请更正我的错误正确理解您的示例。您在服务器端和客户端使用相同的类,问题是die方法在服务器端和客户端执行不同的任务,如果不修改它,您无法重用同一个类。因此事件有助于克服此问题,对吗?您可以在服务器端和客户端为die事件附加任何方法。这有助于我们了解代码的可重用性,例如准确地说,将代码分为更多的部分和更灵活的结构。如果我想在其他地方使用我的玩家类,我可以很容易地做到,因为即使认为玩家类可以在内部处理自己,它仍然在更新其状态的“环境”。我通过使用事件实现了这一点。我认为Button不是一个好例子。例如,在现代WPF中,您可以将命令绑定到一个按钮,这很像设置单播委托。
public void NpcDie(Player sender, EventArgs e)
{
    //who hoo, I can be implemented differently
    //I can even check if sender.Health <= 0
}

public void PlayerDie(Player sender, EventArgs e)
{
}