2009-03-18 14 views
70

Mit Resharper 4.1 habe ich diese interessante Warnung gefunden: "Zugriff auf ein statisches Element eines Typs über einen abgeleiteten Typ". Hier ist ein Beispiel für den Code, wo dies der Fall ist:Verwenden eines statischen Members einer Klasse für einen abgeleiteten Typ?

class A { 
    public static void SomethingStatic() { 
     //[do that thing you do...] 
    } 
} 

class B : A { 
} 

class SampleUsage { 
    public static void Usage() { 
     B.SomethingStatic(); // <-- Resharper warning occurs here 
    } 
} 

Weiß jemand, was gibt es (falls vorhanden), wenn die Verwendung von A statische Mitglieder über B zu machen?

Antwort

80

Ein Ort, an dem es irreführend sein könnte, ist, wenn die Statik eine Fabrikmethode ist, z. Die Klasse WebRequest verfügt über eine Factory-Methode Create, die das Schreiben dieser Art von Code ermöglicht, wenn auf sie über eine abgeleitete Klasse zugegriffen wird.

var request = (FtpWebRequest)HttpWebRequest.Create("ftp://ftp.example.com"); 

Hier request ist vom Typ FtpWebRequest aber es ist verwirrend, weil es aussieht wie es von einer HttpWebRequest (Geschwister-Klasse) erstellt wurde, obwohl die Create Methode tatsächlich auf WebRequest (die Basisklasse) definiert ist. Der folgende Code ist in der Bedeutung gleich, ist aber deutlicher:

var request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com"); 

Letztlich gibt es kein großes Problem, eine statische über einen abgeleiteten Typ zugreifen, aber Code ist oft klarer durch nicht zu tun.

+0

Dies ist ein Problem, an das ich vorher nie gedacht habe. Danke Greg! – Swim

+0

schöne und klare Erklärung mit einem guten Beispiel. – serg10

+0

großartige Erklärung, es war sehr hilfreich. Das erste Ergebnis auf Google auch ^^ – marcgg

15

Es ist normalerweise keine Warnung, nur ein Vorschlag. Sie schaffen unnötig eine Abhängigkeit von etwas.

Angenommen, Sie entscheiden später, dass B nicht erben muss. Wenn Sie dem Ratschlag von Resharper folgen, müssen Sie diese Codezeile nicht ändern.

+1

haben Sie das gleiche Problem mit Instanzmethoden auch. Nach all dieser Logik, warum etwas erben? oder fehle ich etwas? – NullVoxPopuli

+0

@NullVoxPopuli - Es gibt diejenigen, die empfehlen, Implementierungsvererbung insgesamt zu vermeiden. Mehrere beliebte Java- und C# -Bücher weisen darauf hin (siehe auch dieses Papier: http://www.isase.us/wisr3/7.pdf). Aber in jedem Fall, wenn Sie eine Instanzmethode 'Foo' in' A' haben, dann haben Sie eine Instanz von 'B', auf die sich die Variable' b' bezieht, nicht die gleiche Freiheit wie im statischen Fall sag "wo" 'Foo' sollte nachgeschlagen werden. Sie müssen mit "b" beginnen, was auch immer Sie tun. Es ist also nicht das Gleiche wie bei der Statik. –

2

Ja, ich habe das auch gesehen, ich habe immer angenommen, dass es mich nur warnte, weil es unnötig war. A.SomethingStatic(); würde das gleiche tun.

29

B.SomethingStatic() macht die Aussage, dass SomethingStatic ein Mitglied von B ist. Das ist nicht wahr. SomethingStatic ist eindeutig ein Mitglied von A. Die Tatsache, dass es für Mitglieder von B (als ob es ein Mitglied von B war) uneingeschränkt zugänglich ist, ist eine Frage der Bequemlichkeit. Die Tatsache, dass es zugänglich ist, wenn mit einer B qualifiziert, ist IMO, ein Fehler.

+2

+1 imo, deine Erklärung ist die beste hier. –

+0

Ich denke, eine Unterklasse sollte immer jede Eigenschaft einer Oberklasse erben. Besonders für das Projekt, auf dem ich gerade arbeite, ist es sehr hilfreich bei Fabrikmustern. – NullVoxPopuli

+0

Ich stimme nicht zu. Ich habe einen gültigen Fall, wenn das aktuelle Verhalten von Vorteil ist.Hier ist die Idee: 'class Validator: ValidatorBase {}'. Verwendung: 'Validator.CheckNonEmpty (str)'. Vergleichen Sie dies mit 'ValidatorBase .CheckNonEmpty (str)'. – Gebb

Verwandte Themen