【发布时间】:2019-12-04 09:38:20
【问题描述】:
我有一个简单的类,它应该触发一个事件并传入一些对象类型的数据,因为此时我不知道数据的类型。所以我的示例类是
class Foo
{
public virtual event Action<object> OnStateUpdated;
public void Add(Button button)
{
button.Click += Button_Click;
}
protected virtual void Button_Click(Object sender, EventArgs e)
{
OnStateUpdated("This will return data of type object");
}
}
您可以添加一个按钮,单击它时您将收到一个对象类型的字符串。我希望能够传入一个泛型类型,以便在事件被触发时知道类型。我从这个类继承并创建了一个通用的孩子。
class Bar<ValueType> : Foo
{
public override event Action<ValueType> OnStateUpdated;
protected override void Button_Click(Object sender, EventArgs e)
{
OnStateUpdated(default); // this returns data of type ValueType
}
}
这个类应该覆盖事件并传入正确的类型。
如果用户创建
Foo的实例并监听OnStateUpdated,他应该得到object类型的数据。如果他创建
Bar<string>的实例并监听OnStateUpdated,他应该得到string类型的数据。
不幸的是,我无法覆盖该事件,因为它必须是对象类型。所以我目前的解决方案是让我们使用new 关键字。我没有覆盖事件和单击处理程序,而是使用 new 隐藏父级。
为了完整起见,这将是更新的工作代码
class Foo
{
public event Action<object> OnStateUpdated;
// Add method
private void Button_Click(Object sender, EventArgs e)
{
OnStateUpdated("This will return data of type object");
}
}
class Bar<ValueType> : Foo
{
public new event Action<ValueType> OnStateUpdated;
private new void Button_Click(Object sender, EventArgs e)
{
OnStateUpdated(default); // this returns data of type ValueType
}
}
所以我的问题是:这似乎是一个有效的解决方案,还有更好的解决方案吗? Bar 从 Foo 继承 Add 方法,按钮是否总是使用正确的事件处理程序?
【问题讨论】:
-
为什么不让 Foo 本身成为泛型呢?你仍然可以通过创建 Foo
的实例来使用它来返回任何类型,那么你甚至不需要 Bar 类,因为它做同样的事情 -
class Foo<TEventAction>{ ... event Action<TEventAction> OnStateUpdated?当覆盖一个成员时,你必须匹配你发现的它的类型。 -
@GlennvanAcker 对不起,我不能因为
Foo不应该是通用的。这就是我创造孩子的原因
标签: c#