Why does FxCop think initializing fields to the default value is bad?

FX Cop sees it as adding unnecessary code and unnecessary code is bad. I agree with you, I like to see what it's set to, I think it makes it easier to read.

A similar problem we encounter is, for documentation reasons we may create an empty constructor like this

/// <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
    }        
}

The compiler creates this constructor automatically, so FX cop complains but our sandcastle documentation rules require all public methods to be documented, so we just told fx cop not to complain about it.


FxCop has to provide rules for everyone, so if this rule doesn't appeal to you, just exclude it.

Now, I would suggest that if you want to explicitly declare a default value, use a constant (or static readonly variable) to do it. It will be even clearer than initializing with a value, and FXCop won't complain.

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

There can be significant performance benefits from this, in some cases. For details, see this CodeProject article.

The main issue is that it is unnecessary in C#. In C++, things are different, so many professors teach that you should always initialize. The way the objects are initialized has changed in .NET.

In .NET, objects are always initialized when constructed. If you add an initializer, it's possible (typical) that you cause a double initialization of your variables. This happens whether you initialize them in the constructor or inline.

In addition, since initialization is unnecessary in .NET (it always happens, even if you don't explicitly say to initialize to the default), adding an initializer suggests, from a readability standpoint, that you are trying to add code that has a function. Every piece of code should have a purpose, or be removed if unnecessary. The "extra" code, even if it was harmless, suggests that it is there for a reason, which reduces maintainability.


Reed Copsey said specifying default values for fields impacts performance, and he refers to a test from 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;
}

Now eight years and four versions of C# and .NET later I decided to repeat that test under .NET Framework 4.5 and C# 5, compiled as Release with default optimizations using Visual Studio 2012. I was surprised to see that there is still a performance difference between explicitly initializing fields with their default values and not specifying a default value. I would have expected the later C# compilers to optimize those constant assignments away by now.

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

(the rest)

So I peeked inside the constructors of classes A and B in this test, and both are empty:

.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

I could not find a reason in the IL why explicitly assigning default constant values to fields would consume more time. Apparently the C# compiler does optimize the constants away, and I suspect it always did.

So, then the test must be wrong... I swapped the contents of classes A and B, swapped the numbers in the result string, and reran the tests. And lo and behold now suddenly specifying default values is faster.

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

(the rest)

Therefore I conclude that the C# compiler correctly optimizes for the case where you assign default values to fields. It makes no performance difference!


Now we know performance is really not an issue. And I disagree with Reed Copsey's statement "The 'extra' code, even if it was harmless, suggests that it is there for a reason, which reduces maintainability." and agree with Anders Hansson on this:

Think long term maintenance.

  • Keep the code as explicit as possible.
  • Don't rely on language specific ways to initialize if you don't have to. Maybe a newer version of the language will work differently?
  • Future programmers will thank you.
  • Management will thank you.
  • Why obfuscate things even the slightest?

Future maintainers may come from a different background. It really isn't about what is "right" it is more what will be easiest in the long run.

Tags:

Fxcop