4 Stimmen

Beste Möglichkeit, geschützte Felder freizulegen

Ich habe eine Basisklasse wie diese:

 public class BaseModalCommand
 {

    protected object m_commandArgument;
    protected int m_commandID;
    protected int m_enableUIFlags;

    public virtual void OnIdle()
    {
    }

    public virtual void OnResume()
    {
    }

    public virtual void OnStart(int commandID, object argument)
    {
    }

    public virtual void OnStop()
    {
    }

    public virtual int EnableUIFlags
    {
        get
        {
            return this.m_enableUIFlags;
        }
    }
}

Die virtuellen Methoden sollen in abgeleiteten Typen überschrieben werden. Wenn ich es durch FxCop laufen lasse, beschwert es sich darüber, dass keine sichtbaren Instanzfelder deklariert wurden und empfiehlt, es in privat zu ändern und als geschützte Eigenschaft darzustellen.

Haben Sie eine Idee? Ich denke, diese Nachricht kann ignoriert werden.

12voto

Pontus Gagge Punkte 16933

Für jede Klasse gibt es zwei Arten der Verwendung durch Client-Code: Code, der auf Ihre Klasse verweist, und Code, der Ihre Klasse erbt. Es ist allgemein anerkannt, dass die zweite Art der Verwendung bei weitem die am stärksten gekoppelte ist. Änderungen an Ihrer Klasse wirken sich direkt auf deren interne Mechanik aus. Wenn Sie geschützte Mitglieder auf diese Weise offenlegen, bedeutet dies, dass Änderungen in Ihrer Basisklasse die Funktionsweise Ihrer abgeleiteten Klassen auf unvorhersehbare Weise beeinflussen, ohne dass der Code der Basis- und der abgeleiteten Klasse verglichen werden kann. Genauso schlimm ist, dass Ihre abgeleiteten Klassen die Interna der Basisklasse verändern können.

Wenn Sie wirklich interne Datenelemente auf diese Weise offenlegen wollen, verpacken Sie private Datenelemente in geschützte Eigenschaften (wie gisresearch vorschlägt). Diese Eigenschaften (zusammen mit allen geschützten Methoden) bilden die Vererbungsschnittstelle Ihrer Klasse. Wie jede Schnittstelle, die für externe Clients zugänglich ist (sei es durch die Definition von öffentlichen Methoden und Eigenschaften oder durch eine explizite Schnittstellenimplementierung), ist diese Schnittstelle etwas, das Sie verwalten müssen, insbesondere in größeren Codebasen. Eine Schnittstelle kann geändert werden, doch sollte dies eine bewusste Entscheidung sein.

Wenn Sie direkt mit geschützten Datenelementen arbeiten, haben Sie viel weniger Kontrolle über die Abhängigkeiten zwischen Basis- und abgeleiteten Klassen. Glauben Sie mir, dass es sehr unangenehm sein kann, wenn man nicht einmal weiß, welche Auswirkungen eine Änderung haben könnte.

7voto

Eoin Campbell Punkte 42038

Als beste Praxis sollten Ihre Klassenfelder als privat markiert werden und in eine Getter/Setter-Eigenschaft verpackt werden

also anstelle von

protected object m_commandArgument;

utiliser

private object m_commandArgument;

protected object CommandArgument {get; set;}

Theres mehrere Vorteile zu diesem aber eine einfache Verwendung wäre Ausnahmebehandlung/Validierung in Ihrem Setter sein.

z.B..

private string _email;
protected string Email
{ 
   get { return _email; }
   set 
   {
       if(value.IndexOf("@") > 0)
           _email = value;
       else
            throw new ArgumentException("Not a valid Email");
   }
}

6voto

Paul Alexander Punkte 31302

Der Rat von FxCop ist gut. Sie sollten geschützte Felder nicht direkt an abgeleitete Klassen weitergeben. Der von der Basisklasse verwaltete Zustand sollte von der Basisklasse verwaltet werden und niemals direkt von einer abgeleiteten Klasse geändert werden.

1voto

Frank V Punkte 24349

Eigenschaften verwenden. Ändern Sie die Mitgliedsvariablen in private und richten Sie dann geschützte Eigenschaften für jede Mitgliedsvariable ein.

Herzliche Grüße,
Frank

0voto

J.W. Punkte 17431

Grundsätzlich empfiehlt FxCop, dass Sie Folgendes tun sollten

private object m_commandArgument;

protected object CommandArgument
{
   get { return m_commandArgument; }
   set { m_commandArgument =value}
}

Dies beruht auf der OO-Kapselungsregel (eine von drei OO-Regeln). Vielleicht möchten Sie den Wert überprüfen vor zuweisen, und Sie möchten sicherstellen, dass diese nicht direkt von der abgeleiteten Klasse manipuliert wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X