visual valor tipos tabla studio datos conversiones fxcop

tipos - ¿Por qué FxCop piensa que inicializar los campos al valor predeterminado es malo?



tipos de datos en c# visual studio (6)

Debes recordar que las reglas de FxCop son solo pautas, no son irrompibles. Incluso lo dice en la página para la descripción de la regla que mencionó ( http://msdn.microsoft.com/en-us/library/ms182274(VS.80).aspx , énfasis mío):

Cuándo excluir advertencias :

Excluya una advertencia de esta regla si el constructor llama a otro constructor en la misma clase o base que inicializa el campo a un valor no predeterminado. También es seguro excluir una advertencia de esta regla, o deshabilitar la regla por completo, si el rendimiento y el mantenimiento del código no son prioridades .

Ahora, la regla no es del todo incorrecta, pero como dice, esto no es una prioridad para usted, así que simplemente deshabilite la regla.

Al asignar un valor predeterminado predeterminado a un campo (aquí falso a un bool), FxCop dice:

Resolution : "''Bar.Bar()'' initializes field ''Bar.foo'' of type ''bool'' to false. Remove this initialization because it will be done automatically by the runtime."

Ahora, sé que el código como int a = 0 o bool ok = false está introduciendo algo de redundancia, pero para mí me parece una muy buena práctica de código, una que mis maestros insistieron justamente en mi opinión.

No solo la penalización de rendimiento es muy pequeña, lo que es más importante: confiar en el valor predeterminado es confiar en el conocimiento de cada programador para utilizar un código, en cada tipo de datos que viene con un valor predeterminado. (¿Fecha y hora?)

En serio, creo que esto es muy extraño: el mismo programa que debería protegerlo de cometer errores demasiado obvios, ¿está sugiriendo que haga uno, solo para un mayor rendimiento? (estamos hablando del código de inicialización aquí, ¡solo se ejecuta una vez! Los programadores que se preocupan tanto, por supuesto pueden omitir la inicialización (y probablemente deberían usar C o ensamblador :-)).

¿FxCop está cometiendo un error obvio aquí, o hay más?

Dos actualizaciones:

  1. Esto no es solo mi opinión, sino lo que me enseñaron en la universidad (Bélgica). No es que me guste usar un argumentum ad verecundiam , sino solo para demostrar que no es solo mi opinión. Y en cuanto a eso:

  2. Mis disculpas, acabo de encontrar este:

    ¿Debo siempre / nunca / inicializar los campos de objeto a los valores predeterminados?


FX Cop lo ve como agregar código innecesario y código innecesario es malo. Estoy de acuerdo contigo, me gusta ver a qué se debe, creo que hace que sea más fácil de leer.

Un problema similar que encontramos es, por razones de documentación, podemos crear un constructor vacío como este

/// <summary> /// a test class /// </summary> /// <remarks>Documented on 4/8/2009 by richard</remarks> public class TestClass { /// <summary> /// Initializes a new instance of the <see cref="TestClass"/> class. /// </summary> /// <remarks>Documented on 4/8/2009 by Bob</remarks> public TestClass() { //empty constructor } }

El compilador crea este constructor automáticamente, por lo que FX Cop se queja, pero nuestras reglas de documentación del castillo de arena requieren que todos los métodos públicos estén documentados, así que simplemente le dijimos a fx cop que no se quejara al respecto.


FxCop tiene que proporcionar reglas para todos, por lo tanto, si esta regla no le resulta atractiva, simplemente exclúyala.

Ahora, sugeriría que si desea declarar explícitamente un valor predeterminado, use una constante (o variable estática de solo lectura) para hacerlo. Será incluso más claro que la inicialización con un valor, y FXCop no se quejará.

private const int DEFAULT_AGE = 0; private int age = 0; // FXCop complains private int age = DEFAULT_AGE; // FXCop is happy private static readonly DateTime DEFAULT_BIRTH_DATE = default(DateTime); private DateTime birthDate = default(DateTime); // FXCop doesn''t complain, but it isn''t as readable as below private DateTime birthDate = DEFAULT_BIRTH_DATE; // Everyone''s happy


No se basa en que todos los programadores conozcan algún "estándar corporativo" definido localmente que pueda cambiar en cualquier momento, sino en algo definido formalmente en el Estándar. También podrías decir "no usar x++ porque eso depende del conocimiento de cada programador.


Puede haber importantes beneficios de rendimiento de esto, en algunos casos. Para más detalles, vea este artículo de CodeProject.

El principal problema es que no es necesario en C #. En C ++, las cosas son diferentes, así que muchos profesores enseñan que siempre debes inicializar. La forma en que se inicializan los objetos ha cambiado en .NET.

En .NET, los objetos siempre se inicializan cuando se construyen. Si agrega un inicializador, es posible (típico) que cause una doble inicialización de sus variables. Esto sucede ya sea que los inicialice en el constructor o en línea.

Además, dado que la inicialización no es necesaria en .NET (siempre sucede, incluso si no se dice explícitamente que se inicialice con el valor predeterminado), agregar un inicializador sugiere, desde un punto de vista de legibilidad, que está intentando agregar código que tiene un función. Cada pieza de código debe tener un propósito, o ser eliminada si no es necesario. El código "extra", incluso si era inofensivo, sugiere que está ahí por una razón, lo que reduce la capacidad de mantenimiento.


Reed Copsey dijo que la especificación de valores predeterminados para los campos afecta el rendimiento, y se refiere a una prueba de 2005 .

public class A { // Use CLR''s default value private int varA; private string varB; private DataSet varC; } public class B { // Specify default value explicitly private int varA = 0; private string varB = null; private DataSet varC = null; }

Ahora, ocho años y cuatro versiones de C # y .NET más tarde, decidí repetir esa prueba en .NET Framework 4.5 y C # 5, compilada como Release con optimizaciones predeterminadas usando Visual Studio 2012. Me sorprendió ver que todavía hay una diferencia de rendimiento entre inicializar explícitamente los campos con sus valores predeterminados y sin especificar un valor predeterminado. Habría esperado que los compiladores de C # posteriores optimizaran esas tareas constantes lejos ahora.

No init: 512,75 Init on Def: 536,96 Init in Const: 720,50 Method No init: 140,11 Method Init on Def: 166,86

( el resto )

Así que eché un vistazo dentro de los constructores de las clases A y B en esta prueba, y ambos están vacíos:

.method public hidebysig specialname rtspecialname instance void .ctor () cil managed { // Code size 7 (0x7) .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret } // end of method .ctor

No pude encontrar una razón en la IL por la cual la asignación explícita de valores constantes predeterminados a los campos consumiría más tiempo. Al parecer, el compilador de C # optimiza las constantes, y sospecho que siempre lo hizo.

Entonces, la prueba debe estar equivocada ... Cambié el contenido de las clases A y B , intercambié los números en la cadena de resultados y volví a realizar las pruebas. Y he aquí que, de repente, especificar valores predeterminados es más rápido .

No init: 474,75 Init on Def: 464,42 Init in Const: 715,49 Method No init: 141,60 Method Init on Def: 171,78

( el resto )

Por lo tanto, llego a la conclusión de que el compilador de C # se optimiza correctamente para el caso en el que asigna valores predeterminados a los campos. No hace ninguna diferencia de rendimiento!

Ahora sabemos que el rendimiento realmente no es un problema. Y no estoy de acuerdo con la afirmación de Reed Copsey " El código ''extra'', incluso si era inofensivo, sugiere que está ahí por una razón, lo que reduce la capacidad de mantenimiento ", y estoy de acuerdo con Anders Hansson en esto:

Pensar en el mantenimiento a largo plazo.

  • Mantenga el código lo más explícito posible.
  • No confíe en formas específicas de idioma para inicializar si no tiene que hacerlo. ¿Tal vez una versión más nueva del lenguaje funcionará de manera diferente?
  • Los futuros programadores te lo agradecerán.
  • La gerencia te lo agradecerá.
  • ¿Por qué ofuscar las cosas hasta el más mínimo?

Los futuros mantenedores pueden venir de un fondo diferente. Realmente no se trata de lo que es "correcto", es más de lo que será más fácil a largo plazo.