Esiste una convenzione per l’ordine dei modificatori in C #?

Se dovessi usare più di una, quale ordine dovrei usare parole chiave modificatore come:

public , private , protected , virtual , abstract , override , new , static , internal , sealed e tutti gli altri che sto dimenticando.

Se si scarica l’addin di Microsoft StyleCop Visual Studio, è ansible convalidare il codice sorgente in base alle regole utilizzate da alcuni team in Microsoft. A lui piace che il modificatore di accesso venga prima.

EDIT: Microsoft non è di per sé totalmente coerente; squadre diverse usano stili diversi. Per esempio. StyleCop suggerisce di inserire le direttive nel namespace; ma questo non è seguito nel codice sorgente di Roslyn.

Ho dato uno sguardo alle linee guida sulla progettazione di framework di Microsoft e non ho trovato alcun riferimento a quali modificatori di ordine dovrebbero essere inseriti nei membri. Allo stesso modo, uno sguardo alle specifiche del linguaggio C # si è rivelato infruttuoso.


ReSharper

ReSharper , tuttavia, è più imminente. I valori predefiniti per ReSharper 9.0, con modificatori di accesso (che sono esclusivi) e modificatori di eredità (che sono esclusivi), raggruppati insieme sono:

 { public / protected / internal / private / protected internal } // access modifiers new { abstract / virtual / override } // inheritance modifiers sealed static readonly extern unsafe volatile async 

Questo è memorizzato nel file {solution}.dotsettings sotto il

 "/Default/CodeStyle/CodeFormatting/CSharpFormat/MODIFIERS_ORDER/@EntryValue" 

nodo: il ReSharper predefinito 1 è:

  public protected internal private new abstract virtual override sealed static readonly extern unsafe volatile async  

1 ReSharper salva solo le impostazioni che differiscono da quelle predefinite, quindi in generale questo nodo, così com’è, non sarà visto nel file dotsettings .


new static rispetto a static new

La pagina MSDN per Compiler Warning CS0108 fornisce l’esempio di un campo pubblico i su una class base nascosto da un campo statico pubblico i su una class derivata: il loro suggerimento è di cambiare static in static new :

 public class clx { public int i = 1; } public class cly : clx { public static int i = 2; // CS0108, use the new keyword // Use the following line instead: // public static new int i = 2; } 

Allo stesso modo, IntelliSense in Visual Studio 2015 suggerisce anche di cambiare static in static new

CS0108 Visual Studio ha consigliato la modifica

che è lo stesso se anche il campo i nella class base è static .

Detto questo, una ricerca rapida su GitHub ha rilevato che alcuni progetti sovrascrivono questo valore predefinito per inserire static prima , non dopo la new , i modificatori di ereditarietà e sealed , ad esempio le impostazioni di ReSharper per il progetto GitHub di StyleCop :

  public protected internal private static new abstract virtual override sealed readonly extern unsafe volatile async  

tuttavia, poiché la static non può essere utilizzata in combinazione con i modificatori dell’ereditarietà o sealed , questa è solo una distinzione tra new static (predefinita) e static new .

Personalmente preferisco il secondo, ma una ricerca su Google in referenceource.microsoft.com per il new static rispetto a static new dato:

 Order Results new static 203 static new 10 

il che implica che la preferenza (se non la scelta prevalente) in Microsoft è new static .

Di solito inizio con il modificatore di accesso prima, poi virtuale / astratto / sigillato, quindi sovrascrivo / nuovo / ecc. anche se altri potrebbero farlo diversamente. Quasi sempre, tuttavia, il modificatore di accesso sarà il primo.

In alcuni casi ci sono molte possibilità. Ad esempio con la class inferiore C con class base B ,

 public class B { public void X() { } } public class C : B { protected internal new static readonly DateTime X; } 

il campo di tipo DateTime in C ha non meno di cinque distinti modificatori, quindi ce ne sono 5! == 5*4*3*2*1 == 120 5! == 5*4*3*2*1 == 120 modi diversi per scrivere lo stesso campo! Sarebbe molto confuso non avere protected e internal l’uno accanto all’altro, ma è ancora legale.

Non sono sicuro se tutti sono d’accordo su una convenzione per l’ordine. Ad esempio, ho visto alcune persone inserire il new modificatore prima del modificatore del livello di accesso (livello di protezione), sebbene a molte persone piaccia avere sempre prima il modificatore del livello di protezione.