I am wondering: if I load an object from a db4o database, will field initializers always be called?
An example could be a transient field syncRoot, used for object locking, because of thread-safety:
public class Test
{
[Transient]
private object syncRoot = new object();
[Transient]
private object syncRoot2;
public Test()
{
this.syncRoot2 = new object();
}
}
The db4o query is like:
Test mytestObject = (from Test test in session
select test).First();
I can't use syncRoot2
because during the db4o query, the object constructors are not called, so the value will be null. But what about syncRoot
? Is it safe to use field initializers on db4o model objects?
It depends :)
By default no, since db4o will try to avoid calling the ctor and field initializers are executed within the ctor) (at least using C# compiler shipped with VS 2010).
For example, given the following class definition:
public class Item
{
public object o = new object();
}
C# compiler will emit IL (for the constructor) similar to:
.class public auto ansi beforefieldinit Item extends [mscorlib]System.Object
{
.field public object o
.field public notserialized int32 i
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
.maxstack 8
ldarg.0
newobj instance void [mscorlib]System.Object::.ctor() // field initializer
stfld object Item::o // field initializer
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
}
Basically you have two options here:
Hope this helps