2014-11-05 52 views
2

我有一個類,它是空,拋出異常。與事件這樣</p> <pre><code>public class A { public event Func<string, string> Message; public void Calling() { Message("Hello world!"); } } </code></pre> <p>如果我稱之爲<code>Calling()</code>方法,沒有人訂閱了<code>Message</code>事件又如何初始化事件

如何初始化我的事件?

+0

'public event Func Message = _ => null;' – 2014-11-05 19:22:44

+0

關於事件的更深入的討論可以在這裏找到(http://stackoverflow.com/q/3102918/945456)和[這裏](http://stackoverflow.com/q/786383/945456)。 – 2014-11-05 19:24:38

回答

4

你不初始化你的事件,而你需要在你調用的方法來檢查null:

public void Calling() 
{ 
    if (Message != null) 
     Message("Hello World!"); 
} 
1

你不能。

事件是,因爲你已經發現,默認情況下,這就是爲什麼你在使用前確認他們好的做法要求:

public void Calling() 
{ 
    if (Message != null) 
     Message("Hello World"); 
} 

您未使用的返回值出現;有點奇怪,但也許只是因爲這是一個例證。

你也可以把它初始化爲你構造一個空白的功能,但是那只是浪費資源:

public A() 
{ 
    Message += (s) => { return String.Empty; }; 
} 

現在它調用一個什麼都不做功能每次引發該事件的時候,當一個簡單的null檢查解決了這個問題。肯定不是推薦,但它是「初始化」一個事件的唯一方法。

3

事件初始化。價值null。解決的辦法是首先檢查null。規範方法如下所示:

public void Calling() 
{ 
    Func<string, string> handler = Message; 

    if (handler != null) 
    { 
     handler("Hello world!"); 
    } 
} 

請注意事件值複製到本地檢查之前。這可以確保在檢查null和調用它的時間之間不會對事件進行併發更改。在很多程序中,這是不需要的(沒有併發性),您可以安全地直接檢查事件本身。

+0

+1用於處理競賽條件。 – juharr 2014-11-05 19:05:33

2

在課堂上調用您的活動之前檢查null以查看是否有人訂閱了該活動。

public void Calling() 
{ 
    if (Message != null) 
     Message("Hello world!"); 
} 

參見:Events Tutorial

調用的事件:一旦一個類已經宣佈的事件,它可以治療 該事件就像指定的委託類型的字段。如果沒有客戶端將代理連接到 事件,則字段 將爲空,否則它指的是在調用 事件時應該調用的代理。 因此,調用一個事件通常是由第一個 檢查null並然後調用事件完成的。

1

雖然,這不是你的問題,我會把它扔在那裏。您可以通過「空檢查」來檢查是否有人正在收聽該事件。這確保它不會執行該方法(並隨後拋出NullReferenceException)。

public void Calling() 
{ 
    if (Message != null) 
    Message("Hello World"); // Why are you ignoring the return value? 
} 

至於你的實際問題,東西必須具有到A類型的對象的引用(如在示例中定義。

public class B 
{ 
    A MyA; 

    public B() 
    { 
    MyA = new A(); 
    } 
} 

然後,它具有訂閱消息的事件。

public class B() 
{ 
    A MyA; 

    public B() 
    { 
    MyA = new A(); 
    MyA.Message += MessageHandler; 
    } 

    public string MessageHandler(string s) 
    { 
    // Do other code here and ensure you're returning a string as defined in your Message event. 
    return s; 
    } 
} 

注意,MessageHandler可以任意取名。我只是用,爲清楚起見,也可以匿名方法或lambda表達式,而不是一個名爲方法。

相關問題