[英]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.