0

次のようなシリアライズ可能なクラスがあるとします

[Serializable]
    public class DatabaseViewModel:MVVM.ObservableObject 
    {
        //fields
        //properties

        public DatabaseViewModel()
        {
           //if a serialization file exists then deseralize and make this instance equal to it
           //else initialize fields
        }
    }

呼び出しスコープではなく、クラス内からそのようなことを行うことは可能ですか?

呼び出しスコープで私はただやります

var dbvm = new DatabaseViewModel();

次に、コンストラクターに新しいオブジェクトを作成するか、シリアル化されたオブジェクトをロードするかを決定させます。

私のクラスの中で私はこれを試しました

this = //my serialized object 

呼び出しスコープから実行したい場合は、単に実行します

DatabaseViewModel dbvm = null;
if(File.Exists(".../DatabaseViewModel.bin")
dbvm = //deserialize .../DatabaseViewModel.bin
else
dbvm = new DatabaseViewModel();
4

2 に答える 2

5

thisいいえ、オブジェクトの参照を置き換えることはできません。提案されたように、Factory/Builder を使用できます。

ただし、最近デシリアライズされたオブジェクトには、他のオブジェクトとの違いが 1 つあります。それは、他の誰もそのオブジェクトを参照していないということです。したがって、これは不可能ですが:

class MyClass
{
    public MyClass(MyClass arg)
    {
       this = arg;
    }
}

これは可能です

class MyClass
{
   public MyClass(MyClass arg)
   {
      this.CopyFrom(arg);
   }

   void CopyFrom(MyClass m)
   {
      // Assign fields from m.
   }
}

ここで、コピーする引数オブジェクトを、逆シリアル化されたデータを見つけて内部で逆シリアル化するために必要なものに置き換えると、次のようになります。

class MyClass
{
   public MyClass(int id)
   {
      if (FileExistsOnDisk(id))
      {
         MyClass m = DeserializeFromFile(id);
         CopyFrom(m);
      }
      else
      {
          // Normal construction.
      }
   }
}

ただし、とにかく永続化ロジックと IO をコンストラクターに保持したくないため、オブジェクトの作成または逆シリアル化の選択を他のオブジェクト (ファクトリ/ビルダーなど) の責任にするだけで、はるかに優れた設計が得られます。 .

public class MyClassFactory
{
   public MyClass GetObj(int id)
   {
      if (FileExistsOnDisk(id))
         return DeserializeFromFile(id);
      else 
         return new MyClass(id);     
   }
}

「呼び出しスコープから実行したい場合は、実行するだけです」

あなたがやる。

于 2013-10-21T12:40:26.990 に答える