Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8901

C#の標準シリアライズ・デシリアライズを簡単にまとめてみた

$
0
0

まとめてみた

設定とか、何かしらのオブジェクトをざっと保存して、さっと読み込みたいなぁなんて思った時に、シリアライザーという言葉が目に付きました。

でもなんか色々ある...。
というわけでちょっと、簡単に使える感じにまとめてみました。

個人的には 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ると幸せになれるかもです。

ちなみに初投稿。お目汚し失礼しました('ω')ノ


Viewing all articles
Browse latest Browse all 8901

Trending Articles