2011-03-03 27 views
8

He aquí un ejemplo de lo que estoy hablando ...¿Por qué no debe tener acceso a un miembro compartido/estático a través de una variable de instancia?

Public Class Sample1 

    Public Shared Function MyValue() As Integer 
     Return 0 
    End Function 

    Public Sub Code() 
     Dim ThisIsBad = Me.MyValue 
     Dim ThisIsGood = Sample1.MyValue 
    End Sub 

End Class 

Me.MyValue da una advertencia en VB.NET y (el código equivalente da) un error en C#. ¿Hay alguna razón en particular para esto? Me resulta más intuitivo/natural acceder a la función compartida usando 'Me.MyValue', pero lo evito para mantener mis advertencias en 0.

¿Alguien más decidió 'Nah, tiene más sentido hacerlo de otra manera 'o hay alguna razón técnica que no entiendo?

EDIT:

Gracias a todos. Estaba pensando que estaba mal, más como una 'subclase' en OOP. Incluso si algo se declara en la clase base, se accede a través de la instancia que tiene. Pero esa relación no es lo mismo con compartida o estática.

Respuesta

7

Los miembros estáticos, por definición, son declarados en la clase nivel, no en el nivel de instancia, y así acceder a un miembro estático utilizando this (o me en VB) en realidad no se siente bien (y no es justo en C#)

Decir this.something (o me.something) implica que está accediendo a "algo" que es particular, a esa instancia específica, mientras que, de nuevo, los miembros estáticos son compartidos a lo largo todos instancias de esa clase.

+0

Esto. La función MyValue no pertenece a ninguna instancia; por lo tanto, debe accederse fuera de los límites de una sola instancia. Si trato de usar el equivalente de C# de mi.MyValue resultaría en un error de compilación, por lo que incluso si está permitido en VB, es malo. – KeithS

+0

@KeithS: ¿pretendes que sea una respuesta o un comentario sobre mi respuesta? –

+2

Un comentario. Iba a decir exactamente lo mismo que tú, así que simplemente te subí y lo dije a mi manera. :) – KeithS

2

Me apunta a la instancia actual de Sample1, mientras MyValue no pertenecen a la clase en sí. Por lo tanto, me parece bien que VB.NET te advierta.

Por cierto, Java lo hace de la misma manera:

Thread.currentThread().sleep(1000); // warning, as sleep is static 
Thread.sleep(1000); // correct 

Saludos Matthias

3

Se engañosa para el lector del código.

El código debe escribirse para ser leído y entendido por otro programador, pero no conoce todos los detalles del proyecto. Acceder a una variable estática a través de una instancia hace que se vea como un miembro de la instancia. Tendría que verificar la declaración para ver si está equivocado.

Ese "otro programador" podría ser usted después de medio año.

1

Es muy probable que el compilador lo proteja de cometer un error en el caso de que tenga una instancia y un miembro estático con el mismo nombre.

class X { 

    static public void X1() 
    { 
     Console.WriteLine ("Static"); 
    } 

    public void X1 (bool x1 = false) 
    { 
     X1(); // Which one is this calling? 
     Console.WriteLine ("Instance"); 
    } 
} 

void Main() 
{ 
    X.X1(); // Static 
    new X().X1 (false); // Instance 
} 

resultados en:

  • estático
  • estático
  • Instancia
1

no puede acceder a los campos de nivel de clase por this referencia y no se puede acceder a los campos de nivel de objeto de clase de referencia tiene mucho sentido.

Si se va a tener acceso a igualdad de clase por this puntero que podría terminar con la siguiente código extraño

objA.StaticVariable=1; 
objB.StaticVariable=2; 

que podría inducir a error a alguien que en realidad estábamos editando diferentes propiedades o campos, pero si son el acceso de nombre de clase

Class.StaticVariable=1 
Class.StaticVariable=2 

es claro que estamos editando la misma cosa.

También en la memoria, los campos estáticos se almacenan en un lugar completamente diferente (cerca del objeto Type) que los campos del objeto, así que creo que es una diferencia muy clara.

La verdadera pregunta es: ¿por qué no es un error en VB.NET. Supongo que la respuesta es que VB estaba heredando algunas de las antiguas características .NET VB que no eran muy seguras y es un resultado extraño de tal herencia.

Cuestiones relacionadas