¿Existe una convención para el orden de los modificadores en C #?

Si tuviera que usar más de uno, ¿en qué orden debería usar palabras clave modificadoras como:

public , private , protected , virtual , abstract , override , new , static , internal , sealed y cualquier otro que me esté olvidando.

Si descarga el complemento Microsoft StyleCop Visual Studio, puede validar su código fuente contra las reglas que usan algunos equipos en Microsoft. Le gusta el modificador de acceso para estar primero.

EDITAR: Microsoft no es en sí mismo totalmente consecuente; diferentes equipos usan diferentes estilos. P.ej. StyleCop sugiere poner directivas en el espacio de nombres; pero esto no se sigue en el código fuente de Roslyn.

Eché un vistazo a las Pautas de diseño de frameworks de Microsoft y no pude encontrar ninguna referencia a qué modificadores de orden se deben poner en los miembros. Del mismo modo, un vistazo a la especificación del lenguaje C # resultó infructuoso.


ReSharper

ReSharper , sin embargo, es más comunicativo. Los valores predeterminados para ReSharper 9.0, con modificadores de acceso (que son exclusivos) y modificadores de herencia (que son exclusivos), agrupados juntos son:

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

Esto se almacena en el archivo {solution}.dotsettings debajo de

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

nodo: el valor predeterminado 1 de ReSharper es:

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

1 ReSharper solo guarda configuraciones que difieren de las predeterminadas, por lo que, en general, este nodo, tal como está, no se verá en el archivo de dotsettings .


new static vs static new

La página de MSDN para Advertencia de comstackdor CS0108 da el ejemplo de un campo público i en una clase base que está oculto por un campo estático público i en una clase derivada: su sugerencia es cambiar static a 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; } 

Del mismo modo, el IntelliSense en Visual Studio 2015 también sugiere cambiar de static a static new

CS0108 Visual Studio recomienda cambiar

que es lo mismo si el campo i en la clase base también es static .

Dicho esto, una búsqueda superficial en GitHub descubrió que algunos proyectos anulan este valor predeterminado para poner static antes y no después de los new , los modificadores de herencia y sealed , por ejemplo, la configuración ReSharper para el proyecto StyleCop GitHub :

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

sin embargo, como static no se puede usar junto con los modificadores de herencia o sealed , esta es solo una distinción entre new static (la predeterminada) y static new .

Personalmente, prefiero este último, pero una búsqueda en Google en referencesource.microsoft.com para new static vs static new dio:

 Order Results new static 203 static new 10 

lo que implica que la preferencia (si no es la elección prevaleciente) en Microsoft es new static .

Normalmente empiezo con el modificador de acceso primero, luego virtual / abstracto / sellado, luego reemplazo / nuevo / etc. aunque otros podrían hacerlo de manera diferente. Casi invariablemente, el modificador de acceso será el primero, sin embargo.

En algunos casos, hay muchas posibilidades. Por ejemplo, con la clase C inferior con clase base B ,

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

el campo de tipo DateTime en C tiene no menos de cinco modificadores distintos, ¡entonces hay 5! == 5*4*3*2*1 == 120 5! == 5*4*3*2*1 == 120 formas diferentes de escribir el mismo campo! Sería muy confuso no tener protected e internal uno al lado del otro, pero aún es legal.

No estoy seguro de si todos están de acuerdo con una convención para la orden. Por ejemplo, he visto a algunas personas poner el new modificador antes del modificador de nivel de acceso (nivel de protección), aunque a muchas personas les gusta tener siempre el modificador de nivel de protección.