2012-01-27 37 views
3

我是c#開發新手。我只是想研究委託功能。根據我讀過的有關代表的文章和筆記,我嘗試編寫一個示例代碼來實現代理,這些代碼基於我從這些筆記和文章中瞭解的內容。代表事件問題

但我同時運行樣品

得到一個錯誤「對象引用不設置到對象的實例。」

這裏有什麼問題?或者我是否以正確的方式實施了代表?或者我的代理概念是錯誤的?

請幫忙。提前致謝。

我在下面發佈我的代碼。

default.aspx.cs

public partial class _Default : System.Web.UI.Page 
{ 
    TestClass myObject = new TestClass(); 

    protected void Page_Load(object sender, EventArgs e) 
    { 
     myObject.MyDelegateEvent += new TestClass.MyDelegate(myObject_MyDelegateEvent); 
    } 

    void myObject_MyDelegateEvent(object sender, EventArgs e) 
    { 
     Console.WriteLine("Delegate event called"); 
    } 
} 

的TestClass

public class TestClass 
{ 
    public delegate void MyDelegate(object sender, EventArgs e); 

    public event MyDelegate MyDelegateEvent; 

    public TestClass() 
    {  
     MyDelegateEvent(this, null); // Here getting error "Object reference not set to an instance of an object." 

    } 

} 
+2

您無法在構造函數中觸發事件。沒有代碼可能訂閱它們的事件處理程序,直到*構建對象之後。這是一個雞和雞蛋的問題。 – 2012-01-27 13:00:10

回答

6

你所想的是:在當時引發事件在構造函數本身,即當沒有訂閱者因此MyDelegateEvent爲空。

最好的選擇是引發事件的

//Check for not null 
if(MyDelegateEvent != null) 
{ 
    MyDelegateEvent(this, null); 
} 
前空檢查
+1

而且,當然,不是在構造函數中做的...... – Oded 2012-01-27 13:00:38

1

始終測試空引發事件之前:如果沒有處理程序連接到您的事件,當它升起

if (this.MyDelegateEvent != null) 
{ 
    // Raises the event here 
} 

(這是在構造函數中引發的情況),可以引發空引用異常。

編輯: 爲了完整起見,當不使用時的說法,你應該使用EventArgs.Empty而不是null

if (this.MyDelegateEvent != null) 
{ 
    this.MyDelegateEvent(this, EventArgs.Empty); 
} 

此外,還有一個EventHandler委託時,你不這樣做,可以使用指定任何事件參數。這很有用,因爲你不必每次都寫自己的。

1

當你聲明一個事件時,事件被初始化爲null。因此,在您的TestClass構造函數中,您嘗試觸發事件,但事件爲null,這會導致您看到的NullReferenceException

爲了避免這種情況,你需要註冊一個事件處理程序或引發事件之前檢查空:

if (MyDelegateEvent != null) 
{ 
    MyDelegateEvent(...) 
} 

另一個竅門是事件初始化到一個空的委託,當您創建它,這意味着你可以跳過null檢查。

public event MyDelegate MyDelegateEvent = delegate {}; // registers a delegate that does nothing 
0

上面的一些代碼的小點。在檢查和使用之間可以更改MyDelegateEvent。推薦的形式(框架設計指南)是

var del = MyDelegateEvent; 
if (del != null) { 
    del(...); 
} 

心連心,
艾倫的線。

+0

我並不完全同意這個建議。有關此問題的全面討論,請參閱http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety。 – ken2k 2012-01-27 13:42:37

+0

@ ken2k看看主題。非常好。關於通過空值檢查和狀態檢查來調用委託的正確方法有很多討論。我個人喜歡所提到的擴展方法,但是,如果有人打算使用上面的「空檢查和調用」方法,他們是否應該不檢查競爭情況。我錯過了那些據說不需要比賽檢查的東西嗎? – AlanT 2012-01-27 14:30:50

+0

Thankx朋友.. – Arun 2012-01-28 03:50:22