我试图覆盖事件处理程序。除非我还想覆盖参数类,否则工作正常。这是铸造到枚举所必需的。
显示问题的代码
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获得相同的错误,这可能与无法解决此问题有关。
聚苯乙烯。对于行李标记很抱歉,请不要包含问题的名称。
答案 0 :(得分:0)
如果我正确理解了您的问题,那么令您感到困惑的主事情就是错误消息似乎在说明同样适用于Sub_OK
和{ {1}}。也就是说,这两个类都没有Sub_Not_OK<T>
或Base.changed.add
方法,所以这两个类都应该有相同的错误。
顺便说一句&#34;&#34;,但看起来这就是你现在坚持的部分。
答案是你错误地认为Base.changed.remove
没有这些方法。
在类中声明的每个 Sub_OK
必须同时具有event
和add
方法。 (这类似于属性的remove
和get
方法。)您的set
事件包含它们(这就是为什么必须重写它们)和您的Base.changed
类有他们(这就是没有产生错误的原因)。
在C#类中使用Sub_OK
关键字时,您有几个选项。您可以让编译器生成event
和add
方法,也可以自己实现。在您的remove
类和Base
类中,您没有自己实现这些方法,因此编译器会为您执行此操作。在抽象的Sub_OK
类中,因为您的事件被声明为Base
,所以abstract
和add
方法也是如此,并且它们必须在非抽象派生类中被覆盖
在remove
,他们是。您已声明一个非抽象事件,它会覆盖Sub_OK
事件,但您尚未提供明确的Base.changed
和add
方法,因此编译器会为您创建它们一切都很好。
在remove
中,这些方法并不存在。它们不存在,因为您已使用Sub_Not_OK
关键字隐藏基类成员,并创建所有新成员。 new
事件是与基类中声明的事件完全不同的事件,不会覆盖该事件。事实上,新的Sub_Not_OK.changed
甚至不是虚拟的。
当然,这些event
成员是new
的仅成员。因为根据定义,它们是完全新的成员而与基类成员无关,并且由于Sub_Not_OK
中有否其他成员,因此您也明白这一点Sub_Not_OK
中的 nothing 可以覆盖基类的抽象成员。包括Sub_Not_OK
和Base.changed.add
方法。因此错误消息。
现在,除此之外,还不完全清楚你的更广泛目标是什么。一个好的Minimal, Complete, and Verifiable code example包括您希望如何使用这些类的示例会有所帮助。但是,在一天结束的时候,我认为你无法完全完全你想要的东西。
C#没有提供子类化事件的方法。您已尝试解决通过添加Base.changed.remove
关键字重新声明成员时收到的警告,但这并未对声明进行任何更改。它只是明确了你选择隐藏基类成员。特别是,您仍然隐藏成员,而不是覆盖成员。
如果你真的坚持派生类的强类型事件处理程序,那么你需要提供一些机制。最好的方法是简单地声明一个名为的新事件。隐藏基类成员几乎总是一个非常糟糕的主意,因为它使代码难以理解。受影响成员的每次使用都会依赖于上下文,人类很难跟踪上下文。
您可以对可以覆盖的虚拟活动执行某些操作,但是您的问题并不清楚您希望如何使用它。在上面的代码中,假设您可以覆盖基本成员,从基本事件args类派生事件args类,以便派生的new
类可以某种方式使用该派生事件引发事件args类,那么什么?类型仍然匹配(即事件仍然必须使用基本Sub_Not_OK
委托类型),因此可以使用基本事件args类引发事件。如果传递了错误的类型,期望派生事件args类的处理程序必须有一些回退(例如检查类型并忽略事件)。
在一天结束时,您最好重新思考自己选择的道路。您的问题并未包含足够的信息来了解更好的设计,但它确实包含足够的信息,强烈建议您需要不同的更好的设计。