当实现依赖于子 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" 的警告。鉴于这些解释,修复它似乎是个好主意:
- Explanation by JetBrains
- Answer by Jon Skeet
但是,在我的情况下,推荐的解决方案似乎不可行,因为引发事件时,子 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;
Resharper 有一个名为 "Invocation of polymorphic field-like event" 的警告。鉴于这些解释,修复它似乎是个好主意:
- Explanation by JetBrains
- Answer by Jon Skeet
但是,在我的情况下,推荐的解决方案似乎不可行,因为引发事件时,子 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;