2011-07-29 7 views
13

Me sorprendió un poco cuando el compilador se quejó de esto:¿No se puede leer un const en una instancia de clase?

public class UsefulClass 
{ 
    public const String RatingName = @"Ratings\rating"; 
} 

public class OtherClass 
{ 
    public void SomeFunc() 
    { 
     UsefulClass useful = new UsefulClass(); 
     String rating = useful.RatingName; 
    } 
} 

compilador dice, "Miembro estático no se puede acceder con una referencia de instancia; calificar con un nombre del tipo de cambio"

Esto no es No hay problema, String rating = UsefulClass.RatingName; funciona bien. Solo tengo curiosidad por saber qué hay detrás de esto. Tengo una instancia de una clase pública con una constante pública, ¿por qué no puedo obtener los datos de esta manera?

+2

Es un diseño de lenguaje horrible que infringe severamente http://en.wikipedia.org/wiki/Uniform_access_principle ... no hay ninguna razón para ello, y podrían solucionarlo, sin impacto en el código existente, en un momento. –

Respuesta

25

Porque las constantes simplemente no son miembros de la instancia; están estáticamente vinculados a sus respectivos tipos. Del mismo modo que no puede invocar métodos estáticos mediante instancias, no puede acceder a las constantes de clase mediante instancias.

Si necesita obtener una constante de una instancia sin conocer su tipo de primera mano, supongo que podría hacerlo con la reflexión basada en su tipo.

Si está intentando agregar un miembro que no se puede modificar pero pertenece a las instancias, probablemente desee campos o propiedades de solo lectura.

+2

También podría envolver la constante en un getter. –

+1

@BoltClock, traté de probar tu punto con 'String something = this.RatingName' dentro de UsefulClass y obtuve el mismo error, que es consistente con tu respuesta. Siempre he supuesto que 'String something = RatingName' está mirando la instancia, pero ahora veo que usa la descripción Class.Variable de una estática. – TomDestry

+0

@TomDestry: Así es, al igual que cómo llama a los métodos estáticos de una clase utilizando 'StaticMethod()' en lugar de 'this.StaticMethod()'. – BoltClock

10

Una "variable" marcada const es una compilación en tiempo de compilación, no un miembro de instancia. Puede acceder a ella como si fuera una variable estática:

public void SomeFunc() 
{ 
    UsefulClass useful = new UsefulClass(); 
    String rating = UsefulClass.RatingName; // Access as if static 
} 

Dicho esto, yo personalmente envolver esto en una propiedad si se supone que debe ser utilizado como usted la describe de esta forma:

public class UsefulClass 
{ 
    private const string ratingName = @"Ratings\rating"; 

    public string RatingName { get { return ratingName; } } 
} 

Esto haría que tu sintaxis funcionara, pero también sería un mejor diseño, IMO, ya que no expone públicamente tus constantes.

+0

No estoy de acuerdo con el plan de envolverlo en un getter (eso es incorrecto), pero al principio has proporcionado la respuesta correcta al menos (así que te he subido de categoría). –

+0

@NoonSilk, ¿Por qué está mal? – TomDestry

+0

@Noon Seda: Sugeriría que esto sea correcto, y no erróneo, ** si los datos deben estar asociados con una instancia ** (Nombre de la calificación). Así fue como lo mostró el OP, en cuyo caso, se trata de datos de nivel de instancia, y deben estar envueltos en una propiedad (incluso si siempre devuelve una constante). Eso hace que la naturaleza "constante" sea un detalle de implementación del tipo en sí mismo. –

-2

Porque const en C# son implícitamente de tipo estático. Y como a los miembros estáticos solo se puede acceder en miembros de la clase y no en instancias, const no puede hacerlo también.

+1

¿Cómo responde mejor a las respuestas ya provistas? –

Cuestiones relacionadas