2011-02-09 12 views
18

Me alegra que C# no le permita acceder a miembros estáticos como si fueran miembros de instancia. Esto evita un error común en Java:¿Por qué es útil acceder a miembros estáticos "a través de" tipos heredados?

Thread t = new Thread(..); 
t.sleep(..); //Probably doesn't do what the programmer intended. 

Por otro lado, se hace permitirá acceder a los miembros estáticos 'a' tipos derivados. Además de los operadores (donde te ahorra la escritura de moldes), no puedo pensar en ningún caso en el que esto sea realmente útil. De hecho, se anima activamente a errores tales como:

// Nasty surprises ahead - won't throw; does something unintended: 
// Creates a HttpWebRequest instead. 
var ftpRequest = FtpWebRequest.Create(@"http://www.stackoverflow.com"); 

// Something seriously wrong here. 
var areRefEqual = Dictionary<string, int>.ReferenceEquals(dict1, dict2); 

yo personalmente sigo cometiendo errores similares una y otra vez cuando estoy buscando mi camino a través de las API no familiares (Recuerdo de comenzar con los árboles de expresión; golpeo BinaryExpression. en el editor y me preguntaba por qué en la tierra IntelliSense me estaba ofreciendo MakeUnary como una opción).

En mi opinión (miope), esta característica:

  1. No reduce el nivel de detalle; el programador tiene que especificar un nombre de tipo de una forma u otra (excluyendo operadores y casos cuando uno está accediendo a miembros estáticos heredados del tipo actual).
  2. Fomenta errores/código engañoso como el anterior.
  3. Puede sugerir al programador que los métodos estáticos en C# muestren algún tipo de 'polimorfismo', cuando no lo hacen.
  4. (Menor) Presenta las posibilidades de recombinación 'silenciosa', posiblemente no deseada, en la recompilación.

(OMI, los operadores son un caso especial que garantiza su propia discusión.)

Dado que C# es normalmente un "pozo del éxito" lenguaje, ¿por qué existe esta función? No puedo ver sus beneficios (aparte de la 'descubribilidad', que siempre podría resolverse en el IDE), pero veo muchos problemas.

+3

O, lo que es peor, 'UTF8Encoding.ASCII'. – SLaks

+1

Acepto que puede ser un poco engañoso, pero es coherente con el principio de que * los miembros heredados se tratan como miembros del tipo derivado *.Tenga en cuenta que explícitamente * no * permitimos este patrón en parámetros de tipo restringido porque entonces es potencialmente bastante engañoso. Consulte http://blogs.msdn.com/b/ericlippert/archive/2007/06/14/calling-static-methods-on-type-parameters-is-illegal-part-one.aspx para obtener más información. –

Respuesta

7

Acepto que es un error. No sé con qué frecuencia alguien desbordamiento de pila ha publicado el código de:

ASCIIEncoding.ASCII 

etc ... que, aunque inofensivo en términos de ejecución es engañoso en cuanto a la lectura del código.

Obviamente, es demasiado tarde para eliminar esta "función" ahora, aunque supongo que el equipo de C# podría introducir un modo de advertencia súper detallado para este y otros problemas de estilo.

Tal sucesor C# 's va a mejorar las cosas ...

+0

En realidad, solo he visto eso [una vez] (http://stackoverflow.com/questions/4252426/webclient-unicode-which-utf8) en SO. – SLaks

+0

StyleCop podría intentar atraparlos. – SLaks

+3

Como @SLaks dijo, 'UTF8Encoding.ASCII' es aún peor – digEmAll

2

Esto es útil en WinForms.

En cualquier control o formulario, puede escribir MousePosition, MouseButtons o ModifierKeys de usar los static miembros heredados de Control.

Aún es discutible si fue una buena decisión.

+1

Aún podría tener acceso a miembros estáticos "heredados" a través del contexto implícito de escribir una clase, pero no poder acceder a ellos * al especificar un nombre de tipo * que no sea el correcto. –

+0

Es cierto. No estoy seguro de si puedo pensar en algún uso para eso. – SLaks

+0

Estoy de acuerdo con Jon, estas dos cosas son algo ortogonales. Sin embargo, el problema de la reagudización silenciosa aún está allí, aunque es poco probable que surja en WinForms. – Ani

Cuestiones relacionadas