我正在使用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();
}
答案 0 :(得分:1)
使用泛型可能是一种解决方法;每个泛型类都获取静态字段的副本。
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
}
答案 1 :(得分:0)
您需要为每种类型设置一个事件,因为无法确定在基类型上定义事件时委托的注册类型。
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
}
答案 2 :(得分:0)
我不确定这样做是不错的,但您可以在订阅时以及保存数据时指定类型:
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;
}
}
请记住,此代码不是线程安全的,因此如果您想同时从不同的线程使用它,则需要添加锁定。
答案 3 :(得分:0)
为什么它必须是静态的?改为使其成为实例事件。
public event Action Saved;
您必须为每个实例连接它,而不是每个类(或者,在当前情况下,一次),但它会将事件分开。