2012-12-14 71 views
2

我有兩個班,我必須做出一個事件這些類之間進行通信。簡單的事件C#

Class a 
{ 
    public delegate void delegat(int a); 
    public event delegat exit; 
    ... 
    private void a_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     // My event named exit should run here, but I get exception! 
     exit(100); 
    } 
} 

Class b 
{ 
    a instance=new a(); 
    a.exit+=new a.delegat(my_fun); 
    ... 
    private void my_fun(int x) 
    { 
     if(x==100) 
     do_smth; 
     ... 
    } 
} 

但事實是,我得到異常:「對象引用不設置到對象的實例」。 我不明白我在做什麼錯了?我應該在哪裏做一個這樣的新實例? 感謝您的幫助!

+0

你怎麼跑這個代碼?你創建一個b的實例嗎?你確定例外來自於你在b中的同一個例子嗎? – BlackBear

+0

你最大的問題是,你調用類的非靜態方法。你創建了一個稱爲「實例」的實例,但從未使用它,因爲你直接在a上調用一切。改爲使用「實例」調用它們,看看會發生什麼。當我推「B」形式的一些按鈕「A」類​​的實例 – Hoeloe

+0

製成。然後,'a'類表單由a.ShowDialog()函數顯示,我在'a'表單上做了一些事情。正如你可以看到我的事件應該在其他事件觸發時觸發(form'closed'事件)。也許這是錯的嗎? –

回答

2

您試圖分配上本身,而不是實例例如在exit事件

a.exit += ... 

應該是:

instance.exit += ... 

您還沒有檢查是否你exit事件試圖觸發它之前被分配。還有其他問題,你沒有考慮到比賽條件。

這裏的例如處理事件相對安全的方式一般實例

public class A 
{ 
    public delegate void ExitHandler(object sender, int a); 
    public event ExitHandler Exit; 
    ... 
    private void a_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     OnExit(100); 
    } 

    protected virtual void OnExit(int a) 
    { 
     // take a reference to the event (incase it changes) 
     var handler = Exit; 
     if (handler != null) 
     { 
      handler(this, a); 
     } 
    } 

} 

public class B 
{ 
    private A _a; 

    public B() 
    { 
     _a = new A(); 
     _a.Exit += (sender, value) => my_fun(value); 
    } 

    private void my_fun(int x) 
    { 
     if(x==100) 
      do_smth; 
     ... 
    } 
} 
+0

+1,但我也建議使用事件參數(從EventArgs'繼承的對象)約定 – ken2k

+0

@ ken2k這可能更偏好,我更喜歡'EventArgs'而不是委託我自己。但是,使用代表沒有問題。 – James

+0

最好的做法也有'受保護的'方法提升事件 –

0

驗證,如果有任何用戶存在於您的活動提高之前:

if (exit != null) 
    exit(100); 

另一種選擇 - 訂閱虛擬事件處理程序,當你在A類定義事件:

public event delegat exit = (_) => { }; 

還可以使用PascalCase命名類型,事件和方法。並且在接收一個參數,返回void .NET預定義的委託:Action<T>

0

我會改變 「一流的」 代碼調用事件如下:

Class a 
{ 
    public delegate void delegat(int a); 
    public event delegat exit; 
    ... 
    private void a_FormClosed(object sender, FormClosedEventArgs e) 
    { 
    if (this.exit != null) // just in case a_FormClosed fires before assigning the event 
     exit(100);//here should run my event named exit but i get exception! 
    } 
} 
0

試試這個

namespace foo 
    { 
    public delegate void delegat(int a); 
    Class a 
    { 
     public event delegat exit; 
     private void a_FormClosed(object sender, FormClosedEventArgs e) 
     { 
if(exit != null) 
{ 
     exit(100);//here should run my event named exit but i get exception! 
    } 
     } 
    } 
    } 

    Class b 
    { 
     a instance=new a(); 
     instance.exit+=new delegat(my_fun); 
     ... 
     priavte void my_fun(int x) 
     { 
     if(x==100) 
     do_smth; 
     ... 
     } 
    }