Field Initializer in C# Class not Run when Deserializing
On deserialization neither the constructors nor the field initializers are called and a "blank" un-initialized object is used instead.
To resolve it you can make use of the OnDeserializing
or OnDerserialized
attributes to have the deserializer call a function with the following signature:
void OnDeserializing(System.Runtime.Serialization.StreamingContext c);
In that function is where you can initialize whatever was missed within the deserialization process.
In terms of convention, I tend to have my constructor call a method OnCreated()
and then also have deserializating method call the same thing. You can then handle all of the field initialization in there and be sure it's fired before deserialization.
[DataContract]
public abstract class MyAbstract
{
protected Dictionary<int, string> myDict;
protected MyAbstract()
{
OnCreated();
}
private void OnCreated()
{
myDict = new Dictionary<int, string>();
}
[OnDeserializing]
private void OnDeserializing(StreamingContext c)
{
OnCreated();
}
private bool MyMethod(int key)
{
return myDict.ContainsKey(key);
}
private int myProp;
[DataMember]
public int MyProp
{
get { return myProp; }
set { bool b = MyMethod(value); myProp = value; }
}
}
Another approach is to access your field through a protected (in your example) property, and initialise the field using the null-coalescing (??
) operator
protected Dictionary<int, string> myDict = new Dictionary<int, string>();
protected Dictionary<int, string> MyDict
{
get
{
return myDict ?? (myDict = new Dictionary<int, string>());
}
}
The downsides are that you lose the benefits of readonly
, and need to make sure that you only access the value via the property.