2009-08-26 7 views
7

タイトルの質問...要するに、エンティティクラスを返す操作を公開するWCFサービスがあります。クライアント側のクラスは、デフォルトのSystem.Objectの代わりに抽象基本クラスを継承します。抽象基本クラスには、デフォルトのコンストラクターが定義されています。サービスメソッドの1つを呼び出すと、datacontractシリアライザが返されたオブジェクトを生成するときにそのコンストラクタが呼び出されると期待します。ただし、コンストラクタは呼び出されません。一方、エンティティクラスのインスタンスを自分で作成すると、抽象クラスのコンストラクタが呼び出されます。WCFデシリアライザでオブジェクトを初期化するときに、抽象基本クラスのコンストラクタが呼び出されないのはなぜですか?

なぜ、なぜ、回避策がありますか?または、私は何かが恋しいのですか?オブジェクトをマテリアライズするときにdatacontractシリアライザによって呼び出される別のコンストラクタシグネチャがありますか?もしそうでないなら、 "新しいSomeClass()"呼び出しが行うのと同じ方法でコンストラクタを呼び出さずにシリアライザがどのようにオブジェクトをマテリアライズすることができますか?今日はあまりコーヒーを飲んでいませんでしたか(これまで2〜3杯しかありませんでした)?

答えて

11

WCF(と特にDataContractSerializer)はコンストラクタを使用しません。いいえ、実際には(生のオブジェクトを作成するのにFormatterServices.GetUninitializedObjectを使用します)。

すべてのデータは、シリアライザまたはシリアル化されていないフィールドのいずれかで、シリアル化コールバック(たとえば、[OnDeserialized]経由)によって初期化されることが予想されます。

+1

クイックアンサーに感謝します。ワオ。それは私を驚かせます。私はすべてのオブジェクトの初期化によってコンストラクタが呼び出されると考えました。ああ、私は今日何か新しいことを学んだ... :) – KristoferA

+0

それは確かに驚くべきことです。初めて見た時にリフレクターで掘り起こす必要がありました! –

+0

[好奇心から]フォローアップの質問は次のようになります:_それは彼らがそれをそうしましたか?パフォーマンス?私たちの頭を混乱させるには?それとももっと良い理由? :) – KristoferA

1

私は理由を完全に理解していますが、なぜSilverlightでシリアル化コールバックをサポートしていないのか分かりません。 WCF - Silverlight通信では、自分自身をハッキングすることなくデータ契約を初期化することができないようです。だから、私は内部使用のための私の基本クラスのprivateメンバを持っていた場合(たとえば、アンドゥ・リドゥ動作)、デフォルトコンストラクタを使用することはできません。

Stack<PropertyChange> UndoStack = new Stack<PropertyChange>(); 

これは、単に動作しません。それを動作させるには、次のような記述が必要です。

Stack<PropertyChange> _UndoStack; 
Stack<PropertyChange> UndoStack 
{ 
    get 
    { 
      return _UndoStack == null ? (_UndoStack = new Stack<PropertyChange>()) : _UndoStack; 
    } 
} 

これは私にとっては回避策のようです。誰もが良いアイデアを持っていますか?

+0

これは回避策のようですが、nullチェックとセッターの間に競合状態がないことを保証する必要があります。そうしないと、1つのスレッドに対して無効なスタックを返すことがあります。私がこれを解決するために知っている唯一の方法は、少なくともOnDeserializingを使用し、オブジェクトsyncRoot = new object()を作成し、これをUndoStackゲッターでロックすることです(またはこのメソッドでUndoStackインスタンスを直接作成します)。 – eFloh

関連する問題