【问题标题】:override inherited event with generic type用泛型类型覆盖继承的事件
【发布时间】: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&lt;string&gt; 的实例并监听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
    }
}

所以我的问题是:这似乎是一个有效的解决方案,还有更好的解决方案吗? BarFoo 继承 Add 方法,按钮是否总是使用正确的事件处理程序?

【问题讨论】:

  • 为什么不让 Foo 本身成为泛型呢?你仍然可以通过创建 Foo 的实例来使用它来返回任何类型,那么你甚至不需要 Bar 类,因为它做同样的事情
  • class Foo&lt;TEventAction&gt;{ ... event Action&lt;TEventAction&gt; OnStateUpdated?当覆盖一个成员时,你必须匹配你发现的它的类型。
  • @GlennvanAcker 对不起,我不能因为Foo 不应该是通用的。这就是我创造孩子的原因

标签: c#


【解决方案1】:

您可以为事件引入一个通用接口并在两个类中实现它

public interface IFoo<out T>
{
    event Action<T> OnStateUpdated;
}

类实现

class Foo : IFoo<object>
{
    public event Action<object> OnStateUpdated;

    // Add method

    private void Button_Click(Object sender, EventArgs e)
    {
        OnStateUpdated?.Invoke("This will return data of type object");
    }
}

class Bar: IFoo<ValueType>
{
    public event Action<ValueType> OnStateUpdated;

    private new void Button_Click(Object sender, EventArgs e)
    {
        OnStateUpdated?.Invoke(default); // this returns data of type ValueType
    }
}

您还必须正确调用Action,使用thread safe invocation?. 运算符

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 2018-09-27
    • 2015-09-15
    • 2018-08-01
    • 2021-12-28
    • 1970-01-01
    • 2011-07-17
    相关资源
    最近更新 更多