2009-03-18 28 views
70

Usando Resharper 4.1, me he encontrado con esta advertencia interesante: "Acceso a un miembro estático de un tipo a través de un tipo derivado". Aquí está un ejemplo de código de dónde se produce esto:¿Cómo usar el miembro estático de una clase en un tipo derivado?

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 
    } 
} 

¿Alguien sabe qué temas hay (si lo hay) al hacer uso de los miembros estáticos de A a través de B?

Respuesta

80

Un lugar donde puede ser engañoso es cuando la estática es un método de fábrica, p. la clase WebRequest tiene un método de fábrica Create que permitiría escribir este tipo de código si se accede a través de una clase derivada.

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

Aquí request es de tipo FtpWebRequest pero es confuso, ya que parece que fue creado de una (una clase de hermanos) HttpWebRequest a pesar de que el método Create está definido en realidad en WebRequest (la clase base). El siguiente código es idéntico en significado, pero es más claro:

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

En última instancia no hay problema importante acceder a una estática a través de un tipo derivado, pero el código es a menudo más clara al no hacerlo.

+0

Este es un problema que nunca antes había pensado. Gracias Greg! – Swim

+0

explicación agradable y clara con un buen ejemplo. – serg10

+0

gran explicación, fue realmente útil. Primer resultado en google también ^^ – marcgg

15

No es una advertencia, por lo general, solo una sugerencia. Estás creando una dependencia en algo innecesariamente.

Supongamos que luego decide que B no necesita heredar A. Si sigue los consejos de Resharper, no necesitará modificar esa línea de código.

+1

tendrías el mismo problema con los métodos de instancia, también. Por toda esta lógica, ¿por qué heredar algo? o me estoy perdiendo algo? – NullVoxPopuli

+0

@NullVoxPopuli - Hay quienes recomiendan evitar la herencia de implementación por completo. Varios libros populares de Java y C# sugieren esto (véase también este artículo: http://www.isase.us/wisr3/7.pdf). Pero, en cualquier caso, si tiene un método de instancia 'Foo' en' A', entonces, dado un ejemplo de 'B' al que hace referencia la variable' b', no tiene la misma libertad que en el caso estático para diga "dónde" debe buscarse "Foo". Tienes que comenzar con 'b', hagas lo que hagas. Entonces no es realmente lo mismo que con la estática. –

2

Sí, he visto esto también, siempre he supuesto que solo me estaba advirtiendo porque era innecesario. A.SomethingStatic(); haría lo mismo.

29

B.SomethingStatic() hace la declaración que SomethingStatic es un miembro de B. Esto no es verdad. SomethingStatic es inequívocamente un miembro de A. El hecho de que se puede acceder sin reservas a los miembros de B (como si fuera un miembro de B) es una cuestión de conveniencia. El hecho de que es accesible cuando está calificado con un B es, IMO, un error.

+2

+1 imo, tu explicación es la mejor aquí. –

+0

Creo que una subclase siempre debe heredar todas las propiedades de una superclase. Especialmente para el proyecto en el que estoy ahora, es muy útil con los patrones de fábrica. – NullVoxPopuli

+0

No estoy de acuerdo. Tengo un caso válido cuando el comportamiento actual es beneficioso.Aquí está la idea: 'class Validator: ValidatorBase {}'. Uso: 'Validator.CheckNonEmpty (str)'. Compare esto con 'ValidatorBase .CheckNonEmpty (str)'. – Gebb

Cuestiones relacionadas