2016-05-02 4 views
1

Resharper hat eine Warnung namens "Invocation of polymorphic field-like event". In Anbetracht dieser Erklärungen, so scheint es wie eine gute Idee, es zu beheben:Wie behebt man "Aufruf von polymorphem feldähnlichem Ereignis", wenn die Implementierung von der Kindklasse abhängt?

jedoch in meinem Fall die empfohlene Lösung scheint nicht praktikabel zu sein, weil, wenn das Ereignis wird ausgelöst, der type-Parameter in der Kindklasse ist erforderlich. Aus Gründen der Leistung möchte ich ValueToString nicht aufrufen, bis ValueChanging (das normalerweise Null ist) überprüft wurde.

Was ist die empfohlene Lösung in diesem Fall? Ich habe eine Probe meines Codes unten. Die Basisklasse von Foo ist in generische und nicht-generische unterteilt, so dass ich Polymorphie in mehr Fällen nutzen kann.

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> 
+1

Im Moment kann ich nicht sehen, was der Punkt von 'Foo' (die nicht-generische Basisklasse) ist. Funktioniert es, 'ValueChangingEventArgs' generisch in' TValue' zu ​​setzen und 'Foo' komplett zu entfernen? – AakashM

+0

Die nicht-generische Basisklasse existiert so, dass ich z. Erstellen Sie eine Liste von Foo's, oder fügen Sie einen Handler zu jedem 'Foo.ValueChanging' hinzu, ohne dass Sie das' TValue'-Argument jedes einzelnen wissen oder interessieren müssen. Es gibt eine andere Kindklasse, die ich weggelassen habe, 'BazFoo: Foo '. – hypehuman

+0

... obwohl du mich jetzt denkst; in diesem Fall könnte ich Foo durch ein Interface IFoo ersetzen und dasselbe erreichen. – hypehuman

Antwort

0

Stellt sich heraus, wenn ich die Ereignisüberschreibung versiegeln, verschwindet der Fehler. Macht jetzt Sinn, wenn ich darüber nachdenke; jetzt gibt es garantiert nur eine Umsetzung der Veranstaltung.

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

    public sealed override event EventHandler<ValueChangingEventArgs> ValueChanging; 
Verwandte Themen