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 simply say
public class ValueChangedSignal : SignalWrapperBase<T> {
public override event Action<IReadOnlySignal<T>, Sample<T>> Updated;
...
}
and when I in the implementation ValueChangedSignal
try to perform the following
if (Updated != null) { Updated(this, sample); }
I get a ReSharper warning: Invocation of polymorphic field-like event.
I checked the reasoning behind it, but it uses virtual
not abstract
in the example:
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.
I get that I would get two instances if it were virtual
. I would be hiding the base implementation with the actual implementation, however, when I use abstract
I am never making a base implementation, am I? I thought that when I use abstract on some field I am simply forwarding the implementation to the inheriting class, i.e., I am requiring the user of my base class to implement the abstract code.
Is ReSharper giving me a wrong warning? Or am I misunderstanding something?
It's not a false warning and Resharper puts your attention on fact that your derived class can be inherited as well and event overridden.
Let's see an example:
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
}
}
Result of Main(): Event Handled
Everything works as expected: we subscribed to event E, raised event E and can see message from the event subscribtion on the screen.
Now, if we inherit another class from DerivedClass and override event like this:
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;
}
things change and now Main() puts out nothing.
It happens because there is two private fields of event E in object b: one comes from Derived class and the other from MostDerived. That's exactly what Resharper warned about.
If you're sure Derived class will never be inherited and event E overriden, mark Derived as sealed and Resharper warning will disappear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With