Assignment in constructor vs direct assignment
a basic question popped in my head this morning. Here it is:
Is there any difference between doing this:
public class MyClass
{
private object _myField = new object();
...
}
and doing the following:
public class MyClass
{
private object _myField;
开发者_高级运维public MyClass()
{
_myField = new object();
}
...
}
Yes, in the first, the field is initialized before the constructor call. In the second, the field is initialized during the constructor call.
Just to demonstrate casperOne's point...
using System;
public abstract class BaseClass
{
public BaseClass()
{
Console.WriteLine("Result for {0}: {1}", GetType(),
CalledByConstructor());
}
protected abstract string CalledByConstructor();
}
public class VariableInitializer : BaseClass
{
private string foo = "foo";
protected override string CalledByConstructor()
{
return foo;
}
}
public class ConstructorInitialization : BaseClass
{
private string foo;
public ConstructorInitialization()
{
foo = "foo";
}
protected override string CalledByConstructor()
{
return foo;
}
}
public class Test
{
static void Main()
{
new VariableInitializer();
new ConstructorInitialization();
}
}
Here the base class constructor calls an abstract method implemented in the child class - this means we get to see the state of the object before its constructor body starts executing. The results are here:
Result for VariableInitializer: foo
Result for ConstructorInitialization:
As you can see, the variable initializer has already executed - but in the case where initialization only occurs in the constructor body, foo
still has its default value of null.
Calling virtual methods from constructors is generally a very bad idea for precisely this sort of reason.
To add to casperOne's answer, those are the only two possible approaches to initializing a readonly
field. Per MSDN:
When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
In contrast, other fields (ie. not marked readonly
) can be assigned elsewhere in the class, such as via a method call, although that could lead to needing to check its state before usage.
精彩评论