2010-07-08 136 views
4

我在C#初学者和有困难的时候认识的C#活动..这本书我读(图解C#2008)给出了一个例子吧,有我需要问一些事情关于,所以我会在这里通过代码,并指出我不明白的东西。需要帮助了解事件在C#

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)我知道,二本上线后是检查事件包含方法或没有,但什么是OnOneSecound申请宣告该事件发生后的线路?或何时被调用?或它的名字是什么..这不是事件处理程序,我猜对了吗? ElapsedOnOneSecond之间有什么关系?

遗憾的新手问题..并提前:)

回答

7

的OnOneSecond方法将在内部被MyTimerClass时,它需要调用事件被调用。

这是由最控件,包括微软的人使用的公共模式。

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

我倾向于不事件参数传递给该方法OnXXX虽然,例如。

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

然后提高它

this.OnSomeEvent(); 
+0

那么,什么你说的是OnOneSecond方法在功能上只是一个“额外”在这个例子吗? – StingyJack 2010-07-08 12:15:57

+0

由于MyTimerClass什么都不做,它只是没有使用。 – sunside 2010-07-08 12:24:54

0

这可让您手动火从登该类事件的感谢。

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

0

OnOneSecond仅仅是定义引发事件的辅助方法。您可以使用事件,而这样的方法,它仅仅是一个既定的模式来包装用与在开头的名称的方法的if (Elapsed != null)检查...

从技术上讲,你可以只使用Elapsed(source, args)代替OnOneSecond(source, args),但这将引发NullReferenceException如果没有注册听众。

2

这是方法,你叫安全引发事件。

的问题是,你基本上可以称之为

Elapsed(source, args) 

,但如果有连接的情况下没有人,这将引发一个参考空例外。因为事件是空的,当没有人听到它。

更好的解决方案是,您直接添加订阅者到事件。那么你可以直接调用它。因为总会有订户。

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

(注意与它=直接分配。val => { }是Lambda表达式,限定了空的订户。)

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

0

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

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

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

欲了解更多信息,请参阅Events in C# explained in detail