175

Xml シリアライゼーションを行うコードを書いています。以下の機能で。

public static string SerializeToXml(object obj)
{
    XmlSerializer serializer = new XmlSerializer(obj.GetType());
    using (StringWriter writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

引数がパラメーターなしのコンストラクターを持たないクラスのインスタンスである場合、例外がスローされます。

未処理の例外: System.InvalidOperationException: CSharpConsole.Foo は、パラメーターなしのコンストラクターがないため、シリアル化できません。System.Xml.Serialization.TypeDesc.CheckSupported() で System.Xml.Serialization.TypeScope.GetTypeDesc (型の種類、MemberInfo ソース、ブール値の directReference、ブール値の throwOnError) で System.Xml.Serialization.ModelScope.GetTypeModel (型の種類、 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type , XmlRootAttribute root, String defaultNamespace) の Boolean direct Reference) System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultName space) の System.Xml.Serialization. XmlSerializer..ctor(型 type)

xml シリアル化を成功させるために、パラメーターなしのコンストラクターが必要なのはなぜですか?

編集: cfeduke の回答に感謝します。パラメーターなしのコンストラクターは、プライベートまたは内部にすることができます。

4

4 に答える 4

252

オブジェクトの逆シリアル化中に、オブジェクトの逆シリアル化を担当するクラスは、シリアル化されたクラスのインスタンスを作成し、入力するインスタンスを取得した後にのみ、シリアル化されたフィールドとプロパティの入力に進みます。

パラメータがない限り、コンストラクタを作成することも、必要に応じて作成することもできprivateます。internal

于 2008-11-06T05:37:22.070 に答える
77

これは の制限ですXmlSerializerBinaryFormatterand はこれを必要とDataContractSerializer しないことに注意してください。これらは、ether から初期化されていないオブジェクトを作成し、逆シリアル化中に初期化できます。

xml を使用しているため、 / ] を使用DataContractSerializerしてクラスをマークすることを検討することもできますが、これによりスキーマが変更されることに注意してください (たとえば、すべてが要素になるのと同等のものはありません)。[DataContract][DataMember[XmlAttribute]

更新:本当に知りたい場合は、コンストラクターを呼び出さずにオブジェクトを作成するためにBinaryFormatter使用します。FormatterServices.GetUninitializedObject()おそらく危険です。あまり頻繁に使用することはお勧めしません;-p MSDN のコメントも参照してください:

オブジェクトの新しいインスタンスはゼロに初期化され、コンストラクターは実行されないため、オブジェクトは、そのオブジェクトによって有効と見なされる状態を表していない可能性があります。現在のメソッドは、ユーザーがすべてのフィールドにすぐに入力する場合にのみ、逆シリアル化に使用する必要があります。不変型の空のインスタンスを作成しても意味がないため、初期化されていない文字列は作成されません。

私は独自のシリアル化エンジンを持っていますが、それを使用するつもりはありませんFormatterServicesコンストラクター (任意のコンストラクター) が実際に実行されたことを知るのがとても好きです。

于 2008-11-06T08:02:33.320 に答える
0

まず、これはドキュメンテーションに書かれているものです。私はそれがメインのフィールドではなく、あなたのクラスフィールドの1つであると思います-そして、デシリアライザーにパラメーターなしの構築なしでそれをどのように構築させたいですか?

コンストラクターを非公開にする回避策があると思います。

于 2008-11-06T05:47:08.477 に答える