C# 调用类似多态字段的事件

C# 调用类似多态字段的事件,c#,events,polymorphism,overriding,C#,Events,Polymorphism,Overriding,考虑到以下准则: public class TableMain { public virtual event Action UpdateFilter; .... } public class TableSub : TableMain { public override event Action UpdateFilter; public void UpdateQuery() { ..... if (UpdateFilter!=nu

考虑到以下准则:

public class TableMain {
    public virtual event Action UpdateFilter;
    ....
}

public class TableSub : TableMain {
    public override event Action UpdateFilter;

    public void UpdateQuery() {
        .....
        if (UpdateFilter!=null) {
              UpdateFilter(); // Invocation of polymorphic field-like event???
        }
    }
}
在这段代码中,显示了警报“调用类似事件的多态字段”

我的问题是: 这到底是什么意思?这是对糟糕编程实践的警告吗? 另外,以多态方式调用事件是一种不好的做法吗?(知道一个事件只能从声明它的类中引发。)

实际上,这里有两个类似于字段的事件。覆盖将覆盖添加/删除部分,但有两个字段-一个在
TableMain
中,另一个在
TableSub
中。只有
TableSub
中的值才会为非空,除非在
TableMain
中显式设置该值。。。因此,如果
TableMain
试图引发事件本身,它将不会调用与
TableSub
中相同的处理程序集。基本上,它会表现得很奇怪

正确的方法是在
TableMain
中提供一个受保护的方法,以允许子类引发事件:

protected void OnUpdateFilter()
{
    Action handler = UpdateFilter;
    if (handler != null)
    {
        handler();
    }
}
然后将事件设置为非虚拟,并删除
TableSub
中的覆盖


请注意,您的事件签名与事件的正常约定不匹配-不使用
EventHandler

@John的任何原因。关于--“请注意,您的事件签名与事件的常规约定不匹配-有没有不使用EventHandler的原因?”我只是利用现有的“Action”委托,因为在这种情况下,我不需要此事件的订阅服务器中的任何参数(object、eventargs)。这(再次)是一种糟糕的编程实践吗?在这种情况下,创建一个单独的(空)委托是更好的主意吗?@Thomas:有一些方法可以合理地使用它们——例如,您可以记录每个订阅,然后将其传递给基本实现。此外,您还需要能够有效地抽象事件,以便能够将它们放入接口中。@Amby:这只意味着事件订阅者将无法为您的事件使用任何通用事件处理程序。这只是一个惯例,我承认我从来没有发现它是一个特别有用的惯例,但是这些天我倾向于遵守它,除非我有一个不能通过这种方式满足的要求。如果您确实想远离约定,那么使用
操作
就可以了,而且比创建另一个委托类型更简单。假设TableMain中的TableMain和UpdateFilter是抽象的。在这种情况下,在我看来,我们被迫对TableSub中的事件声明使用“override”。然而,ReSharper仍然给出了警告。你怎么认为?这个警告有意义吗?@Timores我也有同样的情况。我认为您仍然收到警告的原因是一个假设的
TableSubSub
可以覆盖该方法。解决方案是在
表sub
中使用
密封覆盖
,它修复了潜在问题并删除了警告。