2013-09-21 41 views
3
public class EventBus<T> 
{ 
    [NotNull] // annotation not valid on this declaration type 
    private static event Action<T> Events; 

    static EventBus() 
    { 
     // we always have a do-nothing event handler so we don't have to worry about null checks and race conditions 
     Events += T => { }; 
    } 

正如評論看到,我明確不想不得不面對空到處檢查活動。這可以通過在構造中分配一個從不調用的默認無操作事件來解決。 Resharper無法自動解決這個問題並不令人驚訝,因此我想用NotNull註釋對其進行註釋。不幸的是,看起來NotNull不能應用於事件,但是Resharper會毫不猶豫地在我打電話給我的事件時提醒我「可能的System.NullReferenceException」。爲什麼我不能將事件標記爲NotNull?

如果ReSharper的是要意識到錯誤,應該可以得到與註解避免它。

+0

何必檢查空,如果你要分配它到一個不太明智的默認值呢?如果這是必須的,那麼爲什麼不只是將你的事件處理程序分配給一個空的委託實例呢? '私人靜態事件動作 Events = _ => {};' –

+0

你是對的,我應該初始化它內聯而不是在構造函數中,因爲這會更清楚。默認的原因是,我*不*必須檢查爲空。目標是,當沒有事件處理程序連接時,事件仍然可以被稱爲Events()。 –

回答

4

如果你想這樣做,你可以改變屬性(把一個標誌AttributeTargets.Event)添加在8版本的事件是工作的支持。

namespace JetBrains.Annotations 
{ 
    /// <summary> 
    /// Indicates that the value of the marked element could never be <c>null</c> 
    /// </summary> 
    /// <example><code> 
    /// [NotNull] public object Foo() { 
    /// return null; // Warning: Possible 'null' assignment 
    /// } 
    /// </code></example> 
    [AttributeUsage(
     AttributeTargets.Method | AttributeTargets.Parameter | 
     AttributeTargets.Property | AttributeTargets.Delegate | 
     AttributeTargets.Field | AttributeTargets.Event, AllowMultiple = false, Inherited = true)] 
    public sealed class NotNullAttribute : Attribute { } 

我認爲他們這樣做是因爲他們認爲對於事件最好在提升前檢查它爲空。如果你試圖調用器使用ReSharper的生成事件,就會產生這樣的:

protected virtual void OnMyEvent() 
{ 
    var handler = MyEvent; 
    if (handler != null) 
     handler(); 
} 

或者你可以明確地實現您的活動:

[NotNull] 
private static Action<T> _eventsInternal = obj => { }; 

private static event Action<T> Events 
{ 
    add { _eventsInternal += value; } 
    remove { _eventsInternal -= value; } 
} 

protected static void OnEvents(T arg) 
{ 
    _eventsInternal(arg); 
} 
+1

感謝您添加我自己的NotNullAttribute的提示。就個人而言,我認爲最好將該字段標記爲NotNull並將其初始化,而不是在您稱之爲事件的每個地方檢查null。添加電話時,有人忘記執行檢查的可能性較小。此外,在檢查null事件並調用它時很容易錯過細微的競爭條件,這是bug的另一個機會。 –

相關問題