2009-11-23 22 views

回答

7

这是一个暴露事件的类的简单实现。

public class ChangeNotifier 
{ 
    // Local data 
    private int num; 

    // Ctor to assign data 
    public ChangeNotifier(int number) { this.num = number; } 

    // The event that can be subscribed to 
    public event EventHandler NumberChanged; 

    public int Number 
    { 
     get { return this.num; } 
     set 
     { 
      // If the value has changed... 
      if (this.num != value) 
      { 
       // Assign the new value to private storage 
       this.num = value; 

       // And raise the event 
       if (this.NumberChanged != null) 
        this.NumberChanged(this, EventArgs.Empty); 
      } 
     } 
    } 
} 

这个类可以使用类似如下:

public void SomeMethod() 
{ 
    ChangeNotifier notifier = new ChangeNotifier(10); 

    // Subscribe to the event and output the number when it fires. 
    notifier.NumberChanged += (s, e) => Console.Writeline(notifier.Number.ToString()); 

    notifier.Number = 10; // Does nothing, this is the same value 
    notifier.Number = 20; // Outputs "20" because the event is raised and the lambda runs. 
} 

关于控制流程中,执行流入SomeMethod()。我们创建一个新的ChangeNotifier,从而调用它的构造函数。这会将10的值分配给私人num成员。

然后,我们使用+=语法订阅事件。这个操作符在右边接受一个委托(在我们的例子中,这个委托是一个lambda),并将它添加到事件上的委托集合中。此操作不会执行我们在ChangeNotifier中编写的任何代码。如果您愿意,可以通过该事件的addremove方法进行定制,但很少需要这样做。

然后我们对Number属性执行一些简单的操作。首先我们分配10,它在Number属性上运行set方法,value = 10。但num成员的价值已经为10,所以最初的条件评估为假,没有任何反应。

然后我们用20做同样的事情。这一次的价值是不同的,所以我们将新值分配给num并且触发事件。首先我们验证事件不是null。如果没有订阅它,它是空的。如果它不为空(例如订阅它),我们使用标准方法/委托语法来启动它。我们只是用事件的参数来调用事件。这将调用订阅了该事件的所有方法,包括将执行Console.WriteLine()的lambda。


亨里克已经成功nitpicked存在,如果一个线程可以在Number的制定者,而另一个线程正在退订的听众的潜在的竞争条件。我不认为有人常见的情况下,谁还不明白事件是如何工作的,但如果你担心这种可能性,修改这些行:

if (this.NumberChanged != null) 
    this.NumberChanged(this, EventArgs.Empty); 

是这样的:

var tmp = this.NumberChanged; 
if (tmp != null) 
    tmp(this, EventArgs.Empty); 
+1

谢谢格雷格。我期待着这样的答案。 – Babu

+1

!= null --line上的竞争条件,因为NumberChanged可以被另一个线程取消订阅,如果你有更多的话。 – Henrik

+1

+1为所有信息。对不起,我是软件开发新手,但是如何编辑3行与上面的2行代码不同,后面3行代码中的“this”是指什么以及它如何解决线程问题?请你能详细说明一下吗?谢谢! –

0

如果您有C背景,您可以将委托视为指向函数的指针。

+1

代表将不会是一个问题。但了解事件对我来说是真正的问题。 – Babu

+0

问题是关于事件。 – nawfal

2
class Program 
    { 
     static void Main(string[] args) 
     { 
      Parent p = new Parent(); 
     } 
    } 

    //////////////////////////////////////////// 

    public delegate void DelegateName(string data); 

    class Child 
    { 
     public event DelegateName delegateName; 

     public void call() 
     { 
      delegateName("Narottam"); 
     } 
    } 

    /////////////////////////////////////////// 

    class Parent 
    { 
     public Parent() 
     { 
      Child c = new Child(); 
      c.delegateName += new DelegateName(print); 
      //or like this 
      //c.delegateName += print; 
      c.call(); 
     } 

     public void print(string name) 
     { 
      Console.WriteLine("yes we got the name : " + name); 
     } 
    } 
1
Class A { 
    public delegate void EventHandler(); 

    public static event EventHandler workComplete(); 

    void doWork(){ 
     // DO WORK 
    } 

    void onWorkComplete(){ 
     // Raise event 
     workComplete(); 
    } 
} 

Class Main { 
    A a = new A(); 
    a.workComplete += new() -> { 
     // On Class Complete Work 
     Console.WriteLine("Work Complete"); 
    }; 
}