更改参数类时,不能覆盖事件处理程序

时间:2017-12-03 01:55:34

标签: c# events override handler

我试图覆盖事件处理程序。除非我还想覆盖参数类,否则工作正常。这是铸造到枚举所必需的。

显示问题的代码

public abstract class Base
{
    public class Args : System.EventArgs
    {
        public System.String arg { get; }
        public Args(System.String Iarg)
            : base()
        {
            arg = Iarg;
        }
    }
    public delegate void Handler(Args e);
    public abstract event Handler changed;
}
public class Sub_OK : Base
{
    public override event Handler changed;
}
public class Sub_Not_OK<TEnum> : Base
{
    new public class Args : System.EventArgs
    {
        public TEnum value { get; }
        public Args(TEnum Ivalue) { value = Ivalue; }
    }

    new public delegate void Handler(Args e);
    new public event Handler changed; // Error here
    //public override event Handler changed; // And error here
    //Including the next 2 lines compiles, but changed_2 can't be used in generic code.
    //public event Handler changed_2;
    //public override event Base.Handler changed;
}

尝试了misc。 new和override的组合,但无法使其编译。

尝试这个&#34;新的公共类Args:Base.Args&#34;没有帮助。

我收到这些错误:

Error CS0534 'Sub_Not_OK<TEnum>' does not implement inherited abstract member 'Base.changed.add'.
Error CS0534 'Sub_Not_OK<TEnum>' does not implement inherited abstract member 'Base.changed.remove'.

顺便说一句,我无法理解为什么我没有为Sub_OK获得相同的错误,这可能与无法解决此问题有关。

聚苯乙烯。对于行李标记很抱歉,请不要包含问题的名称。

1 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么令您感到困惑的事情就是错误消息似乎在说明同样适用于Sub_OK和{ {1}}。也就是说,这两个类都没有Sub_Not_OK<T>Base.changed.add方法,所以这两个类都应该有相同的错误。

顺便说一句&#34;&#34;,但看起来这就是你现在坚持的部分。

答案是你错误地认为Base.changed.remove没有这些方法。

类中声明的每个 Sub_OK必须同时具有eventadd方法。 (这类似于属性的removeget方法。)您的set事件包含它们(这就是为什么必须重写它们)和您的Base.changed类有他们(这就是没有产生错误的原因)。

在C#类中使用Sub_OK关键字时,您有几个选项。您可以让编译器生成eventadd方法,也可以自己实现。在您的remove类和Base类中,您没有自己实现这些方法,因此编译器会为您执行此操作。在抽象的Sub_OK类中,因为您的事件被声明为Base,所以abstractadd方法也是如此,并且它们必须在非抽象派生类中被覆盖

remove,他们是。您已声明一个非抽象事件,它会覆盖Sub_OK事件,但您尚未提供明确的Base.changedadd方法,因此编译器会为您创建它们一切都很好。

remove中,这些方法并不存在。它们不存在,因为您已使用Sub_Not_OK关键字隐藏基类成员,并创建所有新成员。 new事件是与基类中声明的事件完全不同的事件不会覆盖该事件。事实上,新的Sub_Not_OK.changed甚至不是虚拟的。

当然,这些event成员是new成员。因为根据定义,它们是完全新的成员而与基类成员无关,并且由于Sub_Not_OK中有其他成员,因此您也明白这一点Sub_Not_OK中的 nothing 可以覆盖基类的抽象成员。包括Sub_Not_OKBase.changed.add方法。因此错误消息。


现在,除此之外,还不完全清楚你的更广泛目标是什么。一个好的Minimal, Complete, and Verifiable code example包括您希望如何使用这些类的示例会有所帮助。但是,在一天结束的时候,我认为你无法完全完全你想要的东西。

C#没有提供子类化事件的方法。您已尝试解决通过添加Base.changed.remove关键字重新声明成员时收到的警告,但这并未对声明进行任何更改。它只是明确了你选择隐藏基类成员。特别是,您仍然隐藏成员,而不是覆盖成员。

如果你真的坚持派生类的强类型事件处理程序,那么你需要提供一些机制。最好的方法是简单地声明一个名为的新事件。隐藏基类成员几乎总是一个非常糟糕的主意,因为它使代码难以理解。受影响成员的每次使用都会依赖于上下文,人类很难跟踪上下文。

您可以对可以覆盖的虚拟活动执行某些操作,但是您的问题并不清楚您希望如何使用它。在上面的代码中,假设您可以覆盖基本成员,从基本事件args类派生事件args类,以便派生的new类可以某种方式使用该派生事件引发事件args类,那么什么?类型仍然匹配(即事件仍然必须使用基本Sub_Not_OK委托类型),因此可以使用基本事件args类引发事件。如果传递了错误的类型,期望派生事件args类的处理程序必须有一些回退(例如检查类型并忽略事件)。

在一天结束时,您最好重新思考自己选择的道路。您的问题并未包含足够的信息来了解更好的设计,但它确实包含足够的信息,强烈建议您需要不同的更好的设计。