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()at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type、MemberInfo sourc e、Boolean directReference、Boolean throwOnError)at System.Xml.Serialization.ModelScope.GetTypeModel(Type type、ブール直接参照)System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type、XmlRootAttribute root、String defaultNamespace)at System.Xml.Serialization.XmlSerializer..ctor(Type type、String defaultName space)at System.Xml.Serialization XmlSerializer..ctor(タイプタイプ)
XMLのシリアル化を成功させるために、パラメーターなしのコンストラクターが必要なのはなぜですか?
編集:cfedukeの答えをありがとう。パラメーターなしのコンストラクターは、プライベートまたは内部にすることができます。
オブジェクトの逆シリアル化中に、オブジェクトの逆シリアル化を担当するクラスは、シリアル化されたクラスのインスタンスを作成し、移入するインスタンスを取得した後にのみ、シリアル化されたフィールドとプロパティを移入します。
必要に応じて、パラメータなしである限り、コンストラクタをprivate
またはinternal
にすることができます。
これはXmlSerializer
の制限です。 BinaryFormatter
およびDataContractSerializer
do notはこれを必要としないことに注意してください-エーテルから初期化されていないオブジェクトを作成し、逆シリアル化。
Xmlを使用しているので、DataContractSerializer
を使用して[DataContract]
/[DataMember
]でクラスをマークすることを検討できますが、これによりスキーマが変更されることに注意してください(たとえば、[XmlAttribute]
-すべてが要素になります)。
更新:本当に知りたい場合は、BinaryFormatter
などが FormatterServices.GetUninitializedObject()
を使用して、コンストラクターを呼び出さずにオブジェクトを作成します。おそらく危険です。あまり頻繁に使用することはお勧めしません;-p MSDNの備考も参照してください。
オブジェクトの新しいインスタンスはゼロに初期化され、コンストラクターは実行されないため、オブジェクトはそのオブジェクトによって有効と見なされる状態を表さない場合があります。現在のメソッドは、ユーザーがすべてのフィールドにすぐにデータを入力する場合にのみ、逆シリアル化に使用する必要があります。不変型の空のインスタンスを作成しても意味がないため、初期化されていない文字列は作成されません。
own シリアル化エンジンがありますが、FormatterServices
を使用するつもりはありません。コンストラクター(anyコンストラクター)が実際に実行されたことを知っているのはとても好きです。
まず第一に、これは documentation で書かれています。私はそれがあなたのクラスフィールドの1つであり、メインのものではないと思う-そして、どのようにデシリアライザがパラメータなしの構築なしでそれを構築するか?
コンストラクタをプライベートにするための回避策があると思います。