1

私は疑問に思っています: db4o データベースからオブジェクトをロードする場合、フィールド初期化子は常に呼び出されますか?

スレッドセーフのため、オブジェクトのロックに使用される一時的なフィールド syncRoot が例として挙げられます。

public class Test
{
    [Transient]
    private object syncRoot = new object();

    [Transient]
    private object syncRoot2;

    public Test()
    {
        this.syncRoot2 = new object();
    }
}

db4o クエリは次のようになります。

Test mytestObject = (from Test test in session
                     select test).First(); 

syncRoot2db4oクエリ中にオブジェクトコンストラクターが呼び出されないため、値がnullになるため、使用できません。しかし、どうsyncRootですか?db4o モデル オブジェクトでフィールド初期化子を使用しても安全ですか?

4

1 に答える 1

1

場合によります :)

デフォルトではいいえ。db4oはctorの呼び出しを回避しようとし、フィールド初期化子はctor内で実行されます)(少なくともVS 2010に付属のC#コンパイラーを使用)。

たとえば、次のクラス定義があるとします。

public class Item
{
   public object o = new object();
}

C#コンパイラは、次のようなIL(コンストラクタ用)を発行します。

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

基本的に、ここには2つのオプションがあります。

  1. コンストラクター呼び出しを有効にする
  2. Activatedイベントを使用して、一時フィールドを初期化します。

お役に立てれば

于 2012-11-30T10:53:33.630 に答える