The implementation of the abstract event gives a warning “Reocation of polymorphic field-like event” from ReSharper

I have an abstract base class with the following abstract event

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

in my implementation I just say

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

and when I in the implementation of ValueChangedSignal try to do the following

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

I get a warning ReSharper: Invoking a polymorphic field-like event .

I checked the reasoning behind it, but in the example it uses virtual not 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 code block uses an override event declaration to override the implementation of the add and remove methods in the event. Then the field itself will exist in two separate copies: one in the database and one in the derivative. As a result, when working with Derived, you will probably never create an instance of Base MyEvent unless you explicitly set it to some value. And, as a result of this, the behavior when the event is raised in the base class will be different from the behavior in the derived class.

I get that I would get two instances if it were virtual . I would hide the base implementation with the actual implementation, however, when I use abstract , I never do the base implementation, right? I thought that when I use abstract on some field, I just redirect the implementation to the inheriting class, that is, I require the user of my base class to implement the abstract code.

Is ReSharper a False Warning? Or am I not understanding something?

+4
source share
1 answer

This is not a false warning, and Resharper draws your attention to the fact that your derived class can also be inherited, and the event is overridden .

Let's look at an example:

  static void Main(string[] args) { Base b = new Derived(); bE += (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 } } 

Result Main (): event handled

Everything works as expected: we signed up for event E, raised event E and can see the message from the event subscription on the screen.

Now, if we inherit another class from DerivedClass and override the event as follows:

  static void Main(string[] args) { Base b = new MostDerived(); bE += (sender, eventArgs) => { Console.WriteLine("Event Handled"); }; b.Raise(); } class MostDerived : Derived { public override event EventHandler E; } 

things change, and now Main () returns nothing.

This is because object b has two private fields for event E: one comes from the Derived class and the other from MostDerived. That's what Resharper warned about.

If you are sure that the Derived class will never be inherited, and the E event is exceeded, mark Derived as stamped and the Resharper warning will disappear.

+2
source

Source: https://habr.com/ru/post/1491421/


All Articles