c# - 实现抽象事件会从 ReSharper 发出 "Invocation of polymorphic field-like event"警告

标签 c# events resharper abstract-class

我有一个带有以下抽象事件的抽象基类

public abstract class SignalWrapperBase<T> : IReadOnlySignal<T> {
  public abstract event Action<IReadOnlySignal<T>, Sample<T>> Updated;
  ...
}

在我的实现中我只是说

public class ValueChangedSignal : SignalWrapperBase<T> {
  public override event Action<IReadOnlySignal<T>, Sample<T>> Updated;
  ...
}

当我在实现 ValueChangedSignal 时尝试执行以下操作

if (Updated != null) { Updated(this, sample); }

我收到 ReSharper 警告:调用多态字段类事件

我检查了 reasoning在它后面,但它在示例中使用 virtual 而不是 abstract:

public class Base
{
  public virtual event EventHandler MyEvent;
}

public class Derived : Base
{
  public override event EventHandler MyEvent;
  public void SomeMethod()
  {
    var args = ...;
    MyEvent(this, args);
  }
}

The above block of code uses an overriding event declaration to override the implementation of the add and remove methods on an event. The field itself will then exist in two separate instances - one in Base and one in Derived. As a consequence, when working with Derived, you're likely to never instantiate the Base's MyEvent unless you explicitly set it to some value. And, as a result of that, the behavior in the case when the event is raised in the base class would differ from that in the derived class.

我知道如果它是虚拟的,我会得到两个实例。我会用实际实现隐藏基本实现,但是,当我使用 abstract 时,我从来没有进行过基本实现,对吗?我认为当我在某些领域使用抽象时,我只是将实现转发给继承类,即,我要求我的基类的用户实现抽象代码。

ReSharper 是否给我错误的警告?还是我误解了什么?

最佳答案

这不是错误警告,Resharper 让您注意的事实是您的派生类也可以被继承和事件覆盖

让我们看一个例子:

    static void Main(string[] args)
    {
        Base b = new Derived();

        b.E += (sender, eventArgs) => { Console.WriteLine("Event Handled"); };
        b.Raise();
    }

    abstract class Base
    {
        public abstract event EventHandler E;
        public abstract void Raise();
    }

    class Derived : Base
    {
        public override event EventHandler E;
        public override void Raise()
        {
            if (E != null)
                E(this, null); // Resharper: Invocation of polymorphic field-like events
        }
    }

Main() 的结果:事件已处理

一切都按预期进行:我们订阅了事件 E,引发了事件 E,并且可以在屏幕上看到来自事件订阅的消息。

现在,如果我们从 DerivedClass 继承另一个类并像这样覆盖事件:

    static void Main(string[] args)
    {
        Base b = new MostDerived();

        b.E += (sender, eventArgs) => { Console.WriteLine("Event Handled"); };
        b.Raise();
    }

    class MostDerived : Derived
    {
        public override event EventHandler E;
    }

事情变了,现在 Main() 什么都没有

发生这种情况是因为对象b中有两个事件E的私有(private)字段:一个来自Derived类,另一个来自MostDerived。这正是 Resharper 警告的内容。

如果您确定 Derived 类永远不会被继承并且事件 E 被覆盖,请将 Derived 标记为密封,Resharper 警告将消失。

关于c# - 实现抽象事件会从 ReSharper 发出 "Invocation of polymorphic field-like event"警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17653608/

相关文章:

c# - log4net 不写入文件

c# - 部分 C# 应用程序的管理员权限

c# - 处理 .Net 线程中的泄漏

python - 计算Python中一系列关键事件之间的时间

c# - 我可以设置 ReSharper 以将未导入的类用法重命名为它们的全名而不是导入它们的命名空间吗?

c# - 是否有已知的算法来查找 N 个元素中哪 K 个元素的总和最接近整数?

asp.net - 使用事件处理错误,检查是否发生错误并做出相应 react

c# - 如何为多个类似控件编写事件处理程序?

c# - 智能感知中的自定义代码片段

visual-studio - VS 2017 鼠标向后导航停止使用 ReSharper