3

インターフェイスを含むオブジェクトをシリアル化しようとしています。ただし、インターフェイスはシリアル化できません。通常、NonSerializedタグのようなものを使用しますが、事前定義された .NET クラス (例: ) の 1 つなど、変更できないクラスにこの属性を適用する方法がわかりませんSystem.Diagnostics.Process

たとえば、次のコードを考えてみましょう。

using System.Diagnostics
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            XmlSerializer x = new XmlSerializer(typeof(Process));
        }
        catch (Exception e)
        {
            Console.WriteLine(e.InnerException.InnerException.Message);
        }
    }
}

これにより、次の結果が出力されます。

Cannot serialize member System.ComponentModel.Component.Site of type System.ComponentModel.ISite because it is an interface.

システム クラスなど、変更できないクラスで次のいずれかを行う方法はありますか?

  1. シリアル化中に子要素を選択的に無視して、子要素がまったくシリアル化されないようにする
  2. ~と同じことを達成するもので要素をマークするNonSerialized

リフレクションを使用して、シリアル化するクラスと同じメンバーをすべて含むクラスを動的に生成し、ある種のディープ コピーを実行し、それをシリアル化するなどの解決策を考えました。ただし、リフレクション ルートを生成するクラス以外に、このシリアル化タスクを達成する簡単な方法があるかどうかを知りたいと思っています。

4

2 に答える 2

4

既存のタイプのシリアル化が複雑になる場合、最善のオプションは常に次のとおりです。別のDTOモデルを作成します。これはドメインエンティティにていますが、シリアル化とうまく連携するためにのみ存在します。通常は非常に単純です(パラメーターなしのコンストラクター、基本的なアクセサー、検証なしなど)。次に、それらの間でマップします。それ以外の場合は、モグラたたきのゲームをプレイし、実際には気に入らないタイプのシリアライザーを構成します。

XmlSerializerを使用したモグラたたきのゲームが必要な場合:XmlAttributeOverridesインスタンスを作成し、特定のタイプに合わせて手動で構成し(属性インスタンスを追加)、XmlSerializerコンストラクターに渡すことができます。しかし、これは醜く、かなり厄介であり、シリアライザーインスタンスをキャッシュして再利用する必要があります(コンストラクターのオーバーロードを使用する場合、通常の自動アセンブリキャッシュ/再利用は適用されません)。(XmlAttributeOverridesインスタンスから)XmlAttributesインスタンスをタイプごとまたはメンバーごとに取得し、必要に応じてXmlIgnoreプロパティをtrueに設定できます。率直に言って、私はこのアプローチに反対することをお勧めします。

于 2013-01-15T20:36:14.640 に答える
1

通常、自分で実装しているオブジェクトをシリアル化して、このようなインスタンスを完全に制御できるようにします。ISerializable を実装し、そのコンストラクターで Process オブジェクトを受け入れるラッパー オブジェクトを作成します。そうすれば、シリアル化するフィールドを自分で制御できます。

そうは言っても、実行可能なプロセスをシリアル化することは実行可能ではないようです。行データを含むオブジェクトをシリアル化し、それをワイヤの反対側で (逆シリアル化時に) 消費したいと思うと思います。Process クラスは、システム内で実行中のコードのインスタンスを表すため、これをシリアル化するのは奇妙に思えます。

于 2013-01-15T20:37:30.523 に答える