2010-03-19 10 views
6

decir que tengo:¿Por qué no se puede llegar a un miembro estático a través de un nombre de instancia?

class Test 
{ 
     public static int Hello = 5; 
} 

Obviamente, esto funciona:

int j = Test.Hello; 

Pero ¿por qué esto no funciona?

Test test = new Test(); 
int j = test.Hello; 

La instancia no podía tener un miembro nombrado por igual, así que no veo cómo esto podría ser ambigua o no se puede resolver de un compilador.

¿Alguien alguna idea de por qué es esto?

EDIT: ¿Hay alguna otra razón técnica por la que esto debería ser diferente a los diseñadores de idiomas que eligen esto para la legibilidad/claridad/estética/etc.?

+0

Un giro cerebral interesante: ¿Qué pasará si nombra la variable de instancia 'Test' (es decir, use el mismo nombre que la clase)? Compruebe la respuesta aquí: http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx –

+1

con los métodos de extensión de C# 3.0 puede obtener exactamente esto. Estática que se puede llamar como métodos de instancia. Sin embargo, solo funciona para métodos que no son accesorios. –

+0

@AZ: Solo este fin de semana leo sobre ellos y realmente lo hacen exactamente como lo describo. Aparentemente, los puntos positivos superan los puntos negativos. – Toad

Respuesta

14

Otro ángulo:

Supongamos este eran posible. ¿Qué le gustaría que fuera el resultado cuando se accede a un miembro estático a través de una variable de instancia que es null? ¿Le gustaría una excepción de referencia nula (pero por qué, dado que no se requiere ninguna instancia para obtener un miembro estático)? ¿O le gustaría que funcione (en cuyo caso tendría la extraña situación de que algunas invocaciones en esta variable de instancia funcionaron, pero otras no)? De cualquier manera tiene problemas.

+1

@aakashm: excelente respuesta. Esta fue la explicación que estaba buscando. Claramente, uno no quiere tener tal situación. – Toad

+0

@aakashm: Acabo de leer en el libro de John Skeets ayer que los métodos de extensión son estáticos, pero parecen ser métodos de instancia de una clase. En este caso, es válido llamar (lo que parece) a un método de instancia, en una clase que es nula. (y se transforma silenciosamente en una llamada estática) – Toad

11

Recuerde qué métodos estáticos (o propiedades, o campos) son: Pertenecen a una clase, y no a ninguna instancia particular de esa clase. Por eso, se comparten en todas las instancias.

Por lo tanto, es lógico que se tenga acceso a los miembros estáticos a través del nombre de la clase y no a través de un objeto. Es cierto que el lenguaje C# podría haber sido diseñado de manera diferente a este respecto ... pero no fue así.

+0

No podría haberlo dicho mejor +1 – used2could

+0

Así que ... si traduzco lo que está diciendo: no hay razón para no permitirlo a través de un nombre de instancia, OTRO que dejarlo en claro para el lector (y escritor) del código que estamos accediendo a un miembro estático ¿verdad? – Toad

+1

@reinier Si _really_ necesita esto, siempre podría crear una función/propiedad trivial en la clase que pueda devolver/establecer hello? – wasatz

0

Puede leer la explicación detallada de la static keyword on MSDN pero creo que se explica mejor con esta cita

Mientras que una instancia de una clase contiene una copia separada de todos los campos de instancia de la clase, sólo hay una copia de cada campo estático.

Creo que esto podría enrutarse en direcciones de memoria y desplazamientos utilizados por el compilador. Por lo que recuerdo en mi curso de compilación en la escuela, la ubicación de las variables de su instancia se almacenará como desplazamientos desde la primera ubicación de la memoria donde se almacena el objeto. Como solo hay una copia del campo estático, nunca será un desplazamiento fijo para acceder al valor del campo estático.

En cuanto a la ambigüedad de los nombres, esto podría ser tan simple como la colisión del nombre dentro de algo como una tabla de símbolos. Sin embargo, fácilmente podría haber una consideración técnica más profunda.

+0

@rich: entiendo la diferencia entre una variable estática y de instancia. Me preguntaba por qué solo se podía acceder a una variable estática a través del nombre de clase (por lo que si había algún problema subyacente profundo con esto, o si solo era una elección). dada la respuesta de aakashm, veo el problema con eso – Toad

1

Creo que es un diseño de lenguaje defensivo: si declara erróneamente una propiedad como estática y luego la establece/obtiene de varias instancias cuando asumió que era una propiedad de instancia, podría obtener todo tipo de efectos secundarios malvados sin ninguna indicación realmente obvia de lo que está mal.

Al requerir que el desarrollador use el nombre de clase para acceder a la propiedad estática, deja en claro que no es una propiedad de instancia y requiere que el desarrollador sea explícito al codificar que realmente desea acceder a esto como un propiedad estática.

1

"¿Hay alguna otra razón técnica por la que esto debería ser diferente a los diseñadores de idiomas que eligen esto para la legibilidad/claridad/estética/etc.?"

La única otra razón que se me ocurre es que crea aros adicionales para que salte tu compilador (no es que esto sea una gran preocupación). Si las instancias pudieran acceder a las llamadas a métodos estáticos, las instancias tendrían que almacenar todas las compensaciones estáticas o el compilador tendría que realizar un paso adicional en el que buscara un método estático con la misma firma en la clase cuando no fuera capaz de hacerlo. localiza un método no estático en la instancia.

Cuestiones relacionadas