まとめてみた
設定とか、何かしらのオブジェクトをざっと保存して、さっと読み込みたいなぁなんて思った時に、シリアライザーという言葉が目に付きました。
でもなんか色々ある...。
というわけでちょっと、簡単に使える感じにまとめてみました。
個人的には ReactiveProperty がシリアライズできる、できないみたいなところが重要です。
でも、そうなると XmlSerializer しか使えない。
Slim とかもできないみたいですけど、ドキュメントを漁っても ReactivePropertyのシリアライズに関する記事がない...。
探し方が悪い?
そういった使い方をしないとか?
なんちゃってプログラマーの私にはわからない...。
標準のシリアライザー達
XmlSerializer
- 結構汎用的というか、使い勝手がいいイメージのあるシリアライザー
- ReactiveProperty<T> とかもシリアライズできる。(他はなんかできなかった…。シリアライズはカスタムできるらしいので、何かしらこねこねすればいけるんでしょうか?)
- 適用にプロパティを持ったクラスがあるなら、この子に放り込めばいい感じにしてくれる。安パイ的な存在。
- 空のコンストラクタが必須。
BinaryFormatter
- バイナリで高速。(でも場合によりけりてきな文言が目に付く...)
- ReactivePropertyはシリアライズできない。
- クラス属性に [Serializeble] を宣言する。
- 空のコンストラクタが必須。
DataContractSerializer
- 他ではできないDictionaryとか、ほとんどのオブジェクトをシリアライズできる。シリアライザーとしては強力な機能を持っているらしいです。
- ReactivePropertyはシリアライズできない。
- クラス属性に [DataContract] を宣言する。
- プロパティには [DataMember] を付けないとシリアライズされない。Orderとかでシリアライズ順序を指定できる。
- 空のコンストラクタがいらない。(シリアライズ時にコンストラクタが呼び出されない)
DataContractJsonSerializer
- オブジェクトをJSON形式でシリアライズ・デシリアライズできる。
- DataContractSerializerよりも柔軟性がある。
- 後は、XMLとの相互変換するような機能がある。(インテリセンスのオーバーロードに出たのを見ただけで試してないですが…)
- JSON.Netとかライブラリがあるようなのでそちらを使った方がよい?
- ReactivePropertyはシリアライズできない。
XamlWriter
- ButtonとかのUI要素をシリアライズできる。
- 画面レイアウトの保存とかに使える?
XamlReader
- ButtonとかのUI要素をデシリアライズできる。
- 画面レイアウトの復元とかに使える?
以下、コードです。
usingSystem.IO;usingSystem.Runtime.Serialization;usingSystem.Runtime.Serialization.Formatters.Binary;usingSystem.Runtime.Serialization.Json;usingSystem.Windows;usingSystem.Windows.Markup;usingSystem.Xml;usingSystem.Xml.Serialization;namespaceSerializers{publicstaticclassXLizer{/// <summary>/// <see cref="XmlWriter"/> のネームスペース設定/// </summary>privatestaticXmlSerializerNamespacesxmlWriterEmptyNameSpace{get{varempty=newXmlSerializerNamespaces();empty.Add("","");returnempty;}}/// <summary>/// <see cref="XmlWriter"/> のシリアライズ設定/// </summary>privatestaticXmlWriterSettingsxmlWriterSettings{get{returnnewXmlWriterSettings{Indent=true};}}/// <summary>/// <see cref="XmlReader"/> のデシリアライズ設定/// </summary>privatestaticXmlReaderSettingsxmlReaderSettings{get{returnnewXmlReaderSettings{CheckCharacters=false};}}/// <summary>/// <see cref="DataContractJsonSerializer"/> のシリアライズ設定/// </summary>//private static DataContractJsonSerializerSettings dataContractJsonSerializerSettings { get { return new DataContractJsonSerializerSettings { }; } }/// <summary>/// <para><see cref="XmlSerializer"/> を使用して <see cref="object"/> をシリアライズします。</para>/// </summary>publicstaticboolXmlSerialize<T>(stringfilePath,TdataObject){try{usingXmlWriterxmlWriter=XmlWriter.Create(filePath,xmlWriterSettings);XmlSerializerxmlSerializer=newXmlSerializer(typeof(T));xmlSerializer.Serialize(xmlWriter,dataObject,xmlWriterEmptyNameSpace);}catch{returnfalse;}returntrue;}/// <summary>/// <para><see cref="XmlSerializer"/> を使用して <see cref="object"/> をデシリアライズします。</para>/// </summary>publicstaticboolXmlDeserialize<T>(stringfilePath,outTdataObject){try{usingXmlReaderxmlReader=XmlReader.Create(filePath,xmlReaderSettings);XmlSerializerxmlSerializer=newXmlSerializer(typeof(T));varobj=xmlSerializer.Deserialize(xmlReader);dataObject=(T)obj;}catch{dataObject=default;returnfalse;}returntrue;}/// <summary>/// <para><see cref="BinaryFormatter"/> を使用して <see cref="object"/> をシリアライズします。</para>/// <code>/// <para>[<see cref="Serializable"/>]</para>/// <para>class MyClass { ... }</para>/// </code>/// </summary>publicstaticboolBinarySerialize<T>(stringfilePath,TdataObject){try{usingFileStreamfileStream=newFileStream(filePath,FileMode.Create);BinaryFormatterbinaryFormatter=newBinaryFormatter();binaryFormatter.Serialize(fileStream,dataObject);}catch{returnfalse;}returntrue;}/// <summary>/// <para><see cref="BinaryFormatter"/> を使用して <see cref="object"/> をデシリアライズします。</para>/// </summary>publicstaticboolBinaryDeserialize<T>(stringfilePath,outTdataObject){try{usingFileStreamfileStream=newFileStream(filePath,FileMode.Open);BinaryFormatterbinaryFormatter=newBinaryFormatter();varobj=binaryFormatter.Deserialize(fileStream);dataObject=(T)obj;}catch{dataObject=default;returnfalse;}returntrue;}/// <summary>/// <para><see cref="DataContractSerializer"/> を使用して <see cref="object"/> をシリアライズします。</para>/// <code>/// <para>[<see cref="DataContract"/>]</para>/// <para>class MyClass { ... }</para>/// </code>/// <code>/// <para>[<see cref="DataMember"/>]</para>/// <para>string Field { ... }</para>/// </code>/// </summary>publicstaticboolDataContractSerialize<T>(stringfilePath,TdataObject){try{usingXmlWriterxmlWriter=XmlWriter.Create(filePath,xmlWriterSettings);DataContractSerializerdataContractSerializer=newDataContractSerializer(typeof(T));dataContractSerializer.WriteObject(xmlWriter,dataObject);}catch{returnfalse;}returntrue;}/// <summary>/// <para><see cref="DataContractSerializer"/> を使用して <see cref="object"/> をシリアライズします。</para>/// </summary>publicstaticboolDataContractDeserialize<T>(stringfilePath,outTdataObject){try{usingXmlReaderxmlReader=XmlReader.Create(filePath,xmlReaderSettings);DataContractSerializerdataContractSerializer=newDataContractSerializer(typeof(T));varobj=dataContractSerializer.ReadObject(xmlReader);dataObject=(T)obj;}catch{dataObject=default;returnfalse;}returntrue;}/// <summary>/// <para><see cref="DataContractJsonSerializer"/> を使用して <see cref="object"/> をシリアライズします。</para>/// <code>/// <para>[<see cref="DataContract"/>]</para>/// <para>class MyClass { ... }</para>/// </code>/// <code>/// <para>[<see cref="DataMember"/>]</para>/// <para>string Field { ... }</para>/// </code>/// </summary>publicstaticboolDataContractJsonSerialize<T>(stringfilePath,TdataObject){try{usingFileStreamfileStream=newFileStream(filePath,FileMode.Create);DataContractJsonSerializerdataContractJsonSerializer=newDataContractJsonSerializer(typeof(T));dataContractJsonSerializer.WriteObject(fileStream,dataObject);}catch{returnfalse;}returntrue;}/// <summary>/// <para><see cref="DataContractJsonSerializer"/> を使用して <see cref="object"/> をデシリアライズします。</para>/// </summary>publicstaticboolDataContractJsonDeserialize<T>(stringfilePath,outTdataObject){try{usingFileStreamfileStream=newFileStream(filePath,FileMode.Open);DataContractJsonSerializerdataContractJsonSerializer=newDataContractJsonSerializer(typeof(T));varobj=dataContractJsonSerializer.ReadObject(fileStream);dataObject=(T)obj;}catch{dataObject=default;returnfalse;}returntrue;}/// <summary>/// <para><see cref="XamlWriter"/> を使用して <see cref="UIElement"/> をシリアライズします。</para>/// </summary>publicstaticboolXamlSerialize<T>(stringfilePath,TuiElement){try{//string xamlString =// XamlWriter.Save(// uiElement);//File.WriteAllText(// filePath,// xamlString);usingXmlWriterxmlWriter=XmlWriter.Create(filePath,xmlWriterSettings);XamlWriter.Save(uiElement,xmlWriter);}catch{returnfalse;}returntrue;}/// <summary>/// <para><see cref="XamlReader"/> を使用して <see cref="UIElement"/> をデシリアライズします。</para>/// </summary>publicstaticboolXamlDeserialize<T>(stringfilePath,outTuiElement){try{//string xamlString =// File.ReadAllText(// filePath);//var obj =// XamlReader.Parse(// xamlString);//uiElement = (T)obj;usingXmlReaderxmlReader=XmlReader.Create(filePath);varobj=XamlReader.Load(xmlReader);uiElement=(T)obj;}catch{uiElement=default;returnfalse;}returntrue;}}}
まとめ
オブジェクトのシリアライズ・デシリアライズには色々ライブラリが出回ってるみたいですけど、最初のとっかかりとしてはやはり標準を使いたい。というわけなので簡単にまとめてみたわけですが...。
今どきWPFでシリアライズの話?もうやり尽くされてますわ。見たいな感じですよね...。(でも、ざっとまとまってるのがなかったから!)
おまけとして。後は、プロパティにつける属性なんかがあったりします。
属性とはなんぞや? という方は XmlElement とかでggると幸せになれるかもです。
ちなみに初投稿。お目汚し失礼しました('ω')ノ