2010-10-06 19 views
7

Non l'ho mai messo in discussione prima d'ora. Ho un modello di ingresso con un numero di campi, ho voluto presentare i nomi di stringa delle proprietà attraverso il modello di ingresso in modo che la mia griglia può usarli:Perché una classe non può avere una proprietà statica o costante e una proprietà di istanza con lo stesso nome?

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public string Description { get;set; } 

    public const string Code = "Code"; 
} 

Ovviamente, questo dà l'errore:

The type 'SomeGridRow' already contains a definition for 'Code'

Perché il CLR non può gestire due proprietà con lo stesso nome che sono, ai miei occhi, separate?

string code = gridRow.Code;   // Actual member from instantiated class 
string codeField = SomeGridRow.Code; // Static/Const 

Ora sto usando solo una classe figlia chiamato Fields nei miei ingressi ora, in modo da poter usare SomeGridRow.Fields.Code. È un po 'complicato, ma funziona.

risposta

7

Poiché è possibile anche accedere alle proprietà statiche (o, non istanza in questo caso) nello stesso modo (all'interno della stessa classe), e sarebbe un po 'di confusione, per esempio:

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public const string Code = "Code"; 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

Poiché sia ​​questo:

public class SomeGridRow 
{ 
    public string Code { get;set; } 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

E questo:

public class SomeGridRow 
{ 
    public const string Code = "Code"; 
    public void MyMethod() { 
    var thing = Code; //what would this reference? 
    } 
} 

sono modi validi per accedere alle proprietà, st atico o no. Non risponde "perché non posso?" domanda, ma più del perché non è permesso ... sarebbe troppo ambiguo IMO.

+0

Aye, I sup posa è ovvio quando è spiegato in questo modo. Ho sempre dato per scontato che i membri statici fossero accessibili usando il loro vero nome di classe. Parte degli standard di programmazione a cui lavoro. – GenericTypeTea

+1

@GenericTypeTea - E questo è uno standard eccellente, all'interno della classe è dove è il più ambiguo che penso, forse non dovrebbe mai essere stato permesso in questo modo ... ma penso che il modo in cui è finito è probabilmente il compromesso meno confuso. –

+0

Sono d'accordo. È un altro caso di taglia unica che non va bene per tutti ... Non è un grosso problema in realtà. Sono solo schizzinoso. Detesto solo le classi annidate. – GenericTypeTea

3

Probabilmente poteva, ma i progettisti di C# volevano evitare le ambiguità che possono derivare da tale uso (abuso?) Delle caratteristiche del linguaggio.

Tale codice finirebbe per essere confuso e ambiguo per gli utenti (volevo che l'istanza o la chiamata al metodo statico ?, Quale è giusto?).

+0

Gli standard che rispondo sempre dettano che i membri statici devono essere referenziati con il loro nome statico Ie 'Foo' sarebbe sempre' TheStaticClass.Foo'. Quindi l'ambiguità non è un problema che mi riguarderebbe.E 'davvero un peccato! Preferirei avere un'ambiguità potenziale (ma controllata) invece delle classi annidate. – GenericTypeTea

+0

@GenericTypeTea - se solo MS ha scritto C# per te e solo per te;) – Oded

+0

Beh, dovrebbero. Visual Studios 2010 GenericTypeTea edition! Lo comprerei :) – GenericTypeTea

1

In aggiunta ai punti già fatti sull'ambiguità, direi che la denominazione deve essere relooked in questo caso.

Se due variabili/campi hanno esattamente lo stesso nome nello stesso contesto, la classe ma i valori diversi mi sembrano più un problema di denominazione.

Se sono esattamente identici, non sono necessari 2 campi.

Se sono leggermente diversi, è necessario disporre di nomi più precisi.

+0

instantiatedClass.Code == 'Il valore attuale'. TheClass.Code == 'Il nome del campo' da passare nell'origine dati della colonna della griglia. Non mi piacciono i valori di stringa seduti nelle viste. L'unica alternativa è usare le espressioni Lambda e usare la reflection per ottenere MethodName. – GenericTypeTea

+0

@GenericTypeTea - forse è solo il mio modo di farlo ma TheClass.Code per me sarebbe piuttosto più accurato come TheClass.CodeColumnName così come sta per il nome della colonna e non deve essere confuso con theObject.Code - che sta per il valore nella colonna del codice. In questo caso, considererei entrambe queste variabili completamente diverse e quindi hanno nomi diversi. Secondo me, avere "Codice" come nome per entrambi è fuorviante. Ho paura di non ottenere il collegamento tra i nomi e il modo in cui li usi nei tuoi lambda ... – InSane

0

In alcuni linguaggi con una sintassi simile, è possibile accedere a un membro statico tramite un'istanza. Quindi è possibile accedere sia a string.Empty e "abc".Empty.

C# non consente questo (sebbene faccia parte all'interno della classe o di una classe derivata, in quanto è possibile omettere il nome classe per un membro statico e può omettere this per un membro di istanza), principalmente per evitare confusione (lo trovo più utile della confusione tbh, ma sono solo io, mi piace anche l'interruzione del passaggio, quindi cosa ne so).

Dopo aver introdotto una regola più rigida per consentire meno ambiguità, sarebbe controproducente consentire una nuova regola più flessibile sul retro di esso che consentiva di più. Pensa a quanti "perché devo usare this con la proprietà X ma non la proprietà Y?"domande SO avrebbero se fosse permesso (dovremmo forzare this con la proprietà X per essere chiari intendevamo il membro dell'istanza)

Problemi correlati