2009-12-30 25 views
9

Ho riscontrato una situazione in VB.NET e C# (.NET2) con la visibilità dei membri statici/condivisi. Mi sembra un po 'strano in VB.NET:static/Shared in visibilità VB.NET e C#

public class A 
    { 
     private static A instance; 
     public static A Instance 
     { 
      get { return instance; } 
     } 

     public string Name { get { } } 
    } 

utilizzo: A.Instance.Name // unico nome è "visibile"


VB.NET:

Public Class A 
    Private Shared _instance As A 

    Public Shared ReadOnly Property Instance() As A 
    Get 
     Return _instance 
    End Get 
    End Property 


    Public ReadOnly Property Name() As String 
    Get 
     Return "" 
    End Get 
    End Property 

End Class 

utilizzo:

A.Instance.Instance.Instance.Instance... 

// membro condiviso si comporta come una pubblica classe posso ripeterlo all'infinito ..

Si tratta di una svista Microsoft o una "caratteristica" VB.NET?

+3

se questo è vero allora io aggiungo al mio lista di 'perché C# piuttosto che VB' ;-) –

+5

@AdamRalph: e questo sarebbe prematuro e non riflettuto. –

risposta

19

Non è una svista, ma il codice VB comporterà un'avvertenza, il che significa chiaramente: non utilizzare questa notazione.

In VB, i membri statici può accessibile tramite un'istanza, dal momento che a rigor di termini, VB non ha static: VB ha la parola chiave Shared, il che significa che il membro è condiviso tra tutte le istanze, come opposto a static in cui un membro non appartiene a alcuna istanza.

Ora, questa è una distinzione semantica tra quelle parole chiave. Si dà il caso che queste due semantiche distinte tendano ad avere lo stesso identico effetto.

Naturalmente, static in C# è oggi identica a Shared in VB.NET ma la loro eredità è diversa e di Shared VB ha semplicemente una storia diversa e quindi storicamente un significato diverso. Con questo significato,, ha assolutamente senso accedere ai membri Shared tramite un'istanza.

ha senso anche se utilizzato in combinazione con Option Strict Off (battitura sciolto): qui, a volte non si sa tipo di una variabile, ma si potrebbe ancora voglia di accedere a un membro Shared. Ora, non hai scelta, ma per utilizzare un'istanza per accedervi:

Option Strict Off 
' … ' 
Dim o As Object = New A() 
' Somewhere else, we want to access a static member of A but we don’t know A: ' 
Dim instance = o.Instance 
+0

C# sembra essere più preciso e chiaro che VB.NET dovrebbe prendere in considerazione la sua compatibilità "storica" ​​con la famiglia VB. Ad ogni modo, C# non consente duplicati nella visibilità dei membri statici - tramite il nome della classe e l'istanza della classe. Inoltre impedisce l'infinito delle chiamate sul campo come Instance.StaticMember.StaticMember ... questo potrebbe mettere in imbarazzo l'utente dell'istanza della classe. – serhio

0

Il compilatore C# non consente di fare riferimento a una proprietà statica su un'istanza di un oggetto, solo dal tipo stesso. Questa è una restrizione C# piuttosto che .NET. VB.NET consentirà ciò ma avviserà contro di esso.

+0

* Questa è una restrizione C# piuttosto che .NET. * Questa restrizione è buona, IMHO, perché non duplica la visibilità dei membri statici - tramite il nome della classe e l'istanza della classe. Inoltre questo impedisce di "infinitare" le chiamate sul campo come Instance.StaticMember.StaticMember.StaticMember.StaticMember.StaticMember ... – serhio

+0

Non potrei essere più d'accordo. –

9

È una funzionalità; questo non è un bug VB funziona come progettato. Lingue diverse fanno scelte diverse sul fatto che un metodo statico possa essere trattato come un metodo di un'istanza oppure no. VB lo consente. C++ lo consente. C# no.

Ricordare che i criteri di progettazione delle diverse lingue sono diversi e pertanto le decisioni prese sono diverse.Nel team di progettazione C#, apprezziamo molto una definizione linguistica che rende sospetti i modelli illegali; dal momento che non c'è che significa passare un'istanza come ricevitore a un metodo statico (a meno che il calcolo dell'espressione del ricevitore non causi un effetto collaterale) perché quindi consentire all'utente di digitare codice senza senso?

Sul team di progettazione VB, attribuiscono valore al codice funzionante nel modo in cui si intendeva che funzionasse la prima volta che lo si digita; se qualcosa sembra un po 'dubbia, forse dare un avvertimento, ma permetterlo e andare avanti.

Se siete interessati ad alcune delle questioni più sottili nella progettazione delle chiamate statici in C#, ecco una questione interessante:

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

+0

in realtà, poiché considero la mia istanza più * statica * di * condivisa * non mi aspettavo di avere un'altra istanza * nell'istanza * singleton * e quindi una ... – serhio