繁体   English   中英

用泛型类型覆盖继承的事件

[英]override inherited event with generic type

我有一个简单的类,它应该触发一个事件并传入一些 object 类型的数据,因为此时我不知道数据的类型。 所以我的示例类是

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");
    }
}

您可以添加一个按钮,单击它时您将收到一个类型为 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继承了FooAdd方法,按钮是否总是使用正确的事件处理程序?

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

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 ,使用带有?. 线程安全调用?. 操作员

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM