When assigning a default default-value to a field (here false to a bool), FxCop says:
Resolution : "'Bar.Bar()' initializes field 'Bar.foo'
of type 'bool' to false. Remove this initialization
because it will be done automatically by the runtime."
Now, I know that code as int a = 0
or bool ok = false
is introducing some redundancy, but to me it seems a very, very good code-practice, one that my teachers insisted on righteously in my opinion.
Not only is the performance penalty very little, more importantly: relying on the default is relying on the knowledge of each programmer ever to use a piece of code, on every datatype that comes with a default. (DateTime?)
Seriously, I think this is very strange: the very program that should protect you from making all too obvious mistakes, is suggesting here to make one, only for some increased performance? (we're talking about initialization code here, only executed once! Programmers who care that much, can of course omit the initialization (and should probably use C or assembler :-) ).
Is FxCop making an obvious mistake here, or is there more to it?
Two updates :
This is not just my opinion, but what I have been taught at university (Belgium). Not that I like to use an argumentum ad verecundiam, but just to show that it isn't just my opinion. And concerning that:
My apologies, I just found this one:
Should I always/ever/never initialize object fields to default values?
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.
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
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.
It's relies not on every programmer knowing some locally defined "corporate standard" which might change between at any time, but on something formally defined in the Standard. You might as well say "don't using x++
because that relies on the knowledge of every programmer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With