2015-07-19 67 views
1

這是我的代碼:爲什麼我不能註冊作爲參數傳遞的事件?

using System.IO; 
using System; 

public class MyClass1{ 

    event Action _myEvent; 

    public MyClass1(){ 
     var m = new MyClass2(_myEvent); 
     _myEvent(); 
    } 

} 

public class MyClass2{ 
    public MyClass2(Action _event){ 
     _event += MyFunction; 
    } 

    void MyFunction(){ 
     Console.WriteLine("Hi"); 
    } 
} 

class Program 
{ 

static void Main() 
    { 
     var m = new MyClass1(); 
    } 
} 

看來MyClass2不登記傳遞的參數_myEvent。即使MyClass2應該訂閱,調用_myEvent也會導致NullReferenceException。如果我讓_myEvent爲public並讓MyClass2直接註冊到它,而不使用傳遞給它的事件參數,它就可以正常工作。這是爲什麼?

+0

可能重複[什麼是NullReferenceException,我該如何解決它?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-doi-i-fix-它) –

+0

你認爲我怎麼創造它?我從來沒有見過任何人「創造」一個事件。如果我將事件公開並直接註冊給它,而不使用參數,那麼一切正常。 –

+0

你公開哪部分? – DavidG

回答

3

您正在獲得NullReferenceException,因爲_myEvent在從MyClass2構造函數返回後爲null。所以,現在

_event = (Action)Delegate.Combine(_event, (Action)MyFunction); 

構造函數中的你有這將不會獲得通過回,除非你添加一個全新的基準:

在構造爲MyClass2,當你做_event += MyFunction,這是有效的簡寫ref關鍵字到參數。

+0

'_event = Delegate.Combine(_event,(Action)MyFunction);'如果你想編譯它。 – sstan

+0

@sstan幾乎但不完全,但我編輯了一個可編譯的版本。 – DavidG

2

引用有問題。嘗試:

public MyClass2(ref Action _event)

說明

當編譯器編譯的代碼,它產生event成2種方法:add_YourEventremove_YourEvent包含參考到的頭部私人代表註冊代表名單。

問題出現是因爲當您將對象作爲參數傳遞給方法時,它們實際上是2個不同的內存塊。對方法內引用的更改不會影響您在MyClass1中聲明的變量。所以,當執行到這行:

_event += MyFunction; 

基準電壓從null變爲一個對委託的引用,但是這隻會影響傳入的參數。您的變量參考(在MyClass1中聲明)不會更改。

+0

當調用'_event + = MyFunction;'時,'_event'只是一個委託,而不是一個事件,儘管它的名字。所以在這種情況下它並不真正調用add_YourEvent方法。 – sstan

相關問題