需要帮助了解C#中的事件

时间:2010-07-08 11:42:51

标签: c# events

我是C#的初学者,很难理解C#中的事件。我读过的这本书(插图C#2008)给出了一个例子,我需要问一些事情,所以我会过去这里的代码并指出我不理解的事情。

public class MyTimerClass
{
   public event EventHandler Elapsed;
   private void OnOneSecond(object source, EventArgs args)  
   {
     if (Elapsed != null)                
     Elapsed(source, args);
   }
}

class ClassA
{
    public void TimerHandlerA(object obj, EventArgs e) // Event handler
    {
        Console.WriteLine("Class A handler called");
    }
}

class ClassB
{
    public static void TimerHandlerB(object obj, EventArgs e) // Static
    {
        Console.WriteLine("Class B handler called");
    }
}

class Program
{
     static void Main( )
     {
         ClassA ca = new ClassA(); // Create the class object.
         MyTimerClass mc = new MyTimerClass(); // Create the timer object.
         mc.Elapsed += ca.TimerHandlerA; // Add handler A -- instance.
         mc.Elapsed += ClassB.TimerHandlerB; // Add handler B -- static.
         Thread.Sleep(2250);
     }
}

好的,现在声明事件public event EventHandler Elapsed; private void OnOneSecond(object source, EventArgs args)后的行我知道后面的两行是检查事件是否包含方法,但是{{1为了?或什么时候叫它?或它的名字..它不是事件处理程序我猜对吗?以及OnOneSecoundElapsed之间的关系是什么?

抱歉新手问题..并提前感谢:)

5 个答案:

答案 0 :(得分:7)

OnTneSecond方法将在需要调用事件时由MyTimerClass在内部调用。

这是大多数控件使用的常见模式,包括微软控件。

基本上你不需要检查事件是否在多个地方设置,你只需在这一个方法中执行它,然后在内部调用此方法来引发事件。

但是,我倾向于不将事件args传递给OnXXX方法,例如。

public event EventHandler<EventArgs> SomeEvent;
protected virtual void OnSomeEvent()
{
    if (this.SomeEvent !=null)
    {
        this.SomeEvent.Invoke(this,EventArgs.Empty);
    }
}

然后提高它

this.OnSomeEvent();

答案 1 :(得分:2)

这是您调用以安全地引发事件的方法。

问题是,你基本上可以打电话了

Elapsed(source, args)

但如果没有人连接到该事件,则会引发Reference Null异常。当事件为空时,没有人听到它。

更好的解决方案是,您直接将订阅者添加到事件中。然后你可以安全地直接调用它。因为总会有订户。

public event Action<EventArgs> Elapsed = val => { };

(请注意,使用=直接分配。val => { }是一个Lambda表达式,用于定义空订阅者。)

另外,请查看Reactive Framework for .net 如果你想做很多事件,这是正确的解决方案。

答案 2 :(得分:0)

这允许您手动触发班级中的事件。

这是提升内部事件的标准模式,这就是为什么它是私有的。

答案 3 :(得分:0)

OnOneSecond只是一个用于引发事件的辅助方法。您可以使用没有这些方法的事件,它只是一个已建立的模式,用于将if (Elapsed != null)检查包装在名称以On ...开头的方法中。

从技术上讲,您可以使用Elapsed(source, args)代替OnOneSecond(source, args),但如果没有注册的话,则会抛出NullReferenceException

答案 4 :(得分:0)

事件是一种机制,让我们知道发生了一些有趣的事情。

事件使用委托来维护订阅者列表。委托持有订阅事件处理方法的引用,但不知道已定义事件处理方法的类。这意味着引发事件的类与订阅事件的类没有直接耦合。

因此,使用事件会使应用程序中的类松散地相互耦合。这是在应用程序设计中使用事件和委托的一个优点。

有关详细信息,请参阅Events in C# explained in detail