当实现依赖于子 class 时,如何修复 "Invocation of polymorphic field-like event"?

How does one fix "Invocation of polymorphic field-like event" when implementation depends on child class?

Resharper 有一个名为 "Invocation of polymorphic field-like event" 的警告。鉴于这些解释,修复它似乎是个好主意:

但是,在我的情况下,推荐的解决方案似乎不可行,因为引发事件时,子 class 中的类型参数是必需的。出于性能原因,在检查 ValueChanging(通常为 null)之前,我不想调用 ValueToString。

在这种情况下推荐的解决方案是什么?下面是我的代码示例。 Foo 的基础 class 分为泛型和非泛型,这样我就可以在更多情况下利用多态性。

public class ValueChangingEventArgs : EventArgs
{
    public Foo ChangingFoo { get; set; }
    public string NewValueAsString { get; private set; }

    public ValueChangingEventArgs(Foo changingFoo, string newValueAsString)
    {
        ChangingFoo = changingFoo;
        NewValueAsString = newValueAsString;
    }
}

public abstract class Foo
{
    public abstract event EventHandler<ValueChangingEventArgs> ValueChanging;

    private IEnumerable<Foo> _directlyRelated;

    public IEnumerable<Foo> GetRelated()
    {
        var result = new HashSet<Foo>();
        GetRelated(result);
        return result;
    }

    private void GetRelated(HashSet<Foo> resultSoFar)
    {
        foreach (var dr in _directlyRelated)
        {
            if (resultSoFar.Add(dr))
            {
                dr.GetRelated(resultSoFar);
            }
        }
    }
}

public abstract class Foo<TValue> : Foo
{
    private TValue mValue;

    public override event EventHandler<ValueChangingEventArgs> ValueChanging;

    private void OnValueChanging(TValue newValue)
    {
        if (ValueChanging != null)
        {
            ValueChanging(this, new ValueChangingEventArgs(this, ValueToString(newValue)));
        }
    }

    protected abstract string ValueToString(TValue value);

    public void SetValue(TValue newValue)
    {
        if (!newValue.Equals(mValue))
        {
            OnValueChanging(newValue);
            mValue = newValue;
        }
    }
}

public interface IBar
{
    string PossiblyCrazyComputation();
}

public class BarFoo : Foo<IBar>
{
    protected override string ValueToString(IBar value)
    {
        return value.PossiblyCrazyComputation();
    }
}

public class BazFoo : Foo<IBaz>

事实证明,如果我密封事件覆盖,错误就会消失。现在我想起来是有道理的;现在保证只有一个事件的实现。

public abstract class Foo<TValue> : Foo
{
    private TValue mValue;

    public sealed override event EventHandler<ValueChangingEventArgs> ValueChanging;