簡體   English   中英

如何停止其他派生類中的基本靜態事件/動作觸發

[英]How to stop base static events/actions firing in other derived classes

我正在使用WinForms選項卡式MDI界面在C#中處理LOB應用程序。 我有各種帶有DataGridViews的表單,以允許用戶選擇他們感興趣的對象,然后他們可以以新表單查看/編輯。

我的每個主要業務對象都繼承自Entity,其定義如下:

public abstract class Entity
{
    public static event Action Saved;

    internal virtual void OnSaved()
    {
        if (Saved != null)
        {
            Saved();
        }
    }
}

然后,我有了填充網格的對象(這些實際上是從Linq-to-SQL自動生成的類,盡管我可以用普通的類來復制問題):

class Class1 : Entity
{
    //Stuff
}


class Class2 : Entity
{
    //Stuff
}

我想知道何時修改給定類的對象,但是我不在乎哪個實例(因此執行靜態操作),以便可以刷新網格並執行其他活動。

問題是從派生類實例觸發事件時發生的-它也為所有其他派生類觸發。 例如:

Class1.Saved += new Action(s1);
Class2.Saved += new Action(s2);

private void TestIt()
{
    Class2 o2 = new Class2();
    o2.OnSaved();  
}

這將觸發s1和s2,但我只希望觸發特定的一個(即s2)。 做這個的最好方式是什么? 我有很多需要這種行為的類,並希望避免在可能的情況下向每個類添加任何代碼。

更新:

感謝您的所有答復,它們對您有所幫助。

我選擇了一個稍有不同的選項,我承認這似乎很hacky,但對於我的目的來說效果很好。 這涉及通過操作傳遞類型,並讓處理程序進行過濾並調用相關操作。

實體類別:

public abstract class Entity
{
    public static event Action<Type> Saved;


    internal void OnSaved()
    {
        private Action<Type> SavedCopy = Saved;        

        if (SavedCopy != null)
            SavedCopy(this.GetType());
    }
}

掛鈎處理程序:

 Entity.Saved += new Action<Type>(Handler);

示例處理程序方法(此格式因表格而異):

    void Handler(Type obj)
    {
       if (obj==typeof(Class1))
           UpdateGrid();
       else if (obj==typeof(Class2))
           UpdateBasicInfo();
       else if (obj == typeof(Class3))
           DoAnotherThing();
    }

使用泛型可能會變通。 每個通用類都獲取靜態字段的副本。

public abstract class Entity<T>
{
    public static event Action Saved = delegate { };

    internal virtual void OnSaved()
    {
        Saved();
    }
}

class Class1 : Entity<Class1>
{
    //Stuff
}

class Class2 : Entity<Class2>
{
    //Stuff
}

您將需要為每種類型創建一個事件,因為當在基本類型上定義事件時,無法確定委托針對哪種類型注冊。

public abstract class Entity
{
    internal abstract void OnSaved();
}

class Class1 : Entity
{
    public static event Action Saved = () => { };

    internal override void OnSaved()
    {
        this.Saved();
    }

    //Stuff
}

class Class2 : Entity
{
    public static event Action Saved = () => { };

    internal override void OnSaved()
    {
        this.Saved();
    }

    //Stuff
}

我不確定這樣做是一個好主意,但是您可以在訂閱時和保存數據時指定類型:

public abstract class Entity
{
    private static Dictionary<Type, Action> Subscribers
         = new Dictionary<Type, Action>();

    internal virtual void OnSaved()
    {
        OnSaved(GetType());
    }

    private OnSaved(Type type)
    {
        Action subscribed;
        Subscribers.TryGetValue(type, out subscribed);
        if (subscribed != null)
            subscribed();
    }

    public Subscribe(Type type, Action action)
    {
        Action subscribed;
        Subscribers.TryGetValue(type, out subscribed);
        Subscribers[type] = subscribed + action;
    }

    public Unsubscribe(Type type, Action action)
    {
        Action subscribed;
        Subscribers.TryGetValue(type, out subscribed);
        Subscribers[type] = subscribed - action;
    }
}

請記住,此代碼不是線程安全的,因此,如果要同時在不同線程中使用它,則需要添加鎖定。

為什么它必須是靜態的? 使其成為實例事件。

public event Action Saved;

您必須為每個實例連接它,而不是每個類一次(或者在當前情況下為一次),但是它將分隔事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM