#まとめてみた
設定とか、何かしらのオブジェクトをざっと保存して、さっと読み込みたいなぁなんて思った時に、シリアライザーという言葉が目に付きました。
でもなんか色々ある...。
というわけでちょっと、簡単に使える感じにまとめてみました。
個人的には 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要素をデシリアライズできる。
- 画面レイアウトの復元とかに使える?
以下、コードです。
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Json;
using System.Windows;
using System.Windows.Markup;
using System.Xml;
using System.Xml.Serialization;
namespace Serializers
{
public static class XLizer
{
/// <summary>
/// <see cref="XmlWriter"/> のネームスペース設定
/// </summary>
private static XmlSerializerNamespaces xmlWriterEmptyNameSpace { get { var empty = new XmlSerializerNamespaces(); empty.Add("", ""); return empty; } }
/// <summary>
/// <see cref="XmlWriter"/> のシリアライズ設定
/// </summary>
private static XmlWriterSettings xmlWriterSettings { get { return new XmlWriterSettings { Indent = true }; } }
/// <summary>
/// <see cref="XmlReader"/> のデシリアライズ設定
/// </summary>
private static XmlReaderSettings xmlReaderSettings { get { return new XmlReaderSettings { 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>
public static bool XmlSerialize<T>(string filePath, T dataObject)
{
try {
using XmlWriter xmlWriter =
XmlWriter.Create(
filePath,
xmlWriterSettings);
XmlSerializer xmlSerializer =
new XmlSerializer(
typeof(T));
xmlSerializer.Serialize(
xmlWriter,
dataObject,
xmlWriterEmptyNameSpace);
} catch {
return false;
}
return true;
}
/// <summary>
/// <para><see cref="XmlSerializer"/> を使用して <see cref="object"/> をデシリアライズします。</para>
/// </summary>
public static bool XmlDeserialize<T>(string filePath, out T dataObject)
{
try {
using XmlReader xmlReader =
XmlReader.Create(
filePath,
xmlReaderSettings);
XmlSerializer xmlSerializer =
new XmlSerializer(
typeof(T));
var obj =
xmlSerializer.Deserialize(
xmlReader);
dataObject = (T)obj;
} catch {
dataObject = default;
return false;
}
return true;
}
/// <summary>
/// <para><see cref="BinaryFormatter"/> を使用して <see cref="object"/> をシリアライズします。</para>
/// <code>
/// <para>[<see cref="Serializable"/>]</para>
/// <para>class MyClass { ... }</para>
/// </code>
/// </summary>
public static bool BinarySerialize<T>(string filePath, T dataObject)
{
try {
using FileStream fileStream =
new FileStream(
filePath,
FileMode.Create);
BinaryFormatter binaryFormatter =
new BinaryFormatter();
binaryFormatter.Serialize(
fileStream,
dataObject);
} catch {
return false;
}
return true;
}
/// <summary>
/// <para><see cref="BinaryFormatter"/> を使用して <see cref="object"/> をデシリアライズします。</para>
/// </summary>
public static bool BinaryDeserialize<T>(string filePath, out T dataObject)
{
try {
using FileStream fileStream =
new FileStream(
filePath,
FileMode.Open);
BinaryFormatter binaryFormatter =
new BinaryFormatter();
var obj =
binaryFormatter.Deserialize(
fileStream);
dataObject = (T)obj;
} catch {
dataObject = default;
return false;
}
return true;
}
/// <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>
public static bool DataContractSerialize<T>(string filePath, T dataObject)
{
try {
using XmlWriter xmlWriter =
XmlWriter.Create(
filePath,
xmlWriterSettings);
DataContractSerializer dataContractSerializer =
new DataContractSerializer(
typeof(T));
dataContractSerializer.WriteObject(
xmlWriter,
dataObject);
} catch {
return false;
}
return true;
}
/// <summary>
/// <para><see cref="DataContractSerializer"/> を使用して <see cref="object"/> をシリアライズします。</para>
/// </summary>
public static bool DataContractDeserialize<T>(string filePath, out T dataObject)
{
try {
using XmlReader xmlReader =
XmlReader.Create(
filePath,
xmlReaderSettings);
DataContractSerializer dataContractSerializer =
new DataContractSerializer(
typeof(T));
var obj =
dataContractSerializer.ReadObject(
xmlReader);
dataObject = (T)obj;
} catch {
dataObject = default;
return false;
}
return true;
}
/// <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>
public static bool DataContractJsonSerialize<T>(string filePath, T dataObject)
{
try {
using FileStream fileStream =
new FileStream(
filePath,
FileMode.Create);
DataContractJsonSerializer dataContractJsonSerializer =
new DataContractJsonSerializer(
typeof(T));
dataContractJsonSerializer.WriteObject(
fileStream,
dataObject);
} catch {
return false;
}
return true;
}
/// <summary>
/// <para><see cref="DataContractJsonSerializer"/> を使用して <see cref="object"/> をデシリアライズします。</para>
/// </summary>
public static bool DataContractJsonDeserialize<T>(string filePath, out T dataObject)
{
try {
using FileStream fileStream =
new FileStream(
filePath,
FileMode.Open);
DataContractJsonSerializer dataContractJsonSerializer =
new DataContractJsonSerializer(
typeof(T));
var obj =
dataContractJsonSerializer.ReadObject(
fileStream);
dataObject = (T)obj;
} catch {
dataObject = default;
return false;
}
return true;
}
/// <summary>
/// <para><see cref="XamlWriter"/> を使用して <see cref="UIElement"/> をシリアライズします。</para>
/// </summary>
public static bool XamlSerialize<T>(string filePath, T uiElement)
{
try {
//string xamlString =
// XamlWriter.Save(
// uiElement);
//File.WriteAllText(
// filePath,
// xamlString);
using XmlWriter xmlWriter =
XmlWriter.Create(
filePath,
xmlWriterSettings);
XamlWriter.Save(
uiElement,
xmlWriter);
} catch {
return false;
}
return true;
}
/// <summary>
/// <para><see cref="XamlReader"/> を使用して <see cref="UIElement"/> をデシリアライズします。</para>
/// </summary>
public static bool XamlDeserialize<T>(string filePath, out T uiElement)
{
try {
//string xamlString =
// File.ReadAllText(
// filePath);
//var obj =
// XamlReader.Parse(
// xamlString);
//uiElement = (T)obj;
using XmlReader xmlReader =
XmlReader.Create(
filePath);
var obj =
XamlReader.Load(
xmlReader);
uiElement = (T)obj;
} catch {
uiElement = default;
return false;
}
return true;
}
}
}
#まとめ
オブジェクトのシリアライズ・デシリアライズには色々ライブラリが出回ってるみたいですけど、最初のとっかかりとしてはやはり標準を使いたい。というわけなので簡単にまとめてみたわけですが...。
今どきWPFでシリアライズの話?もうやり尽くされてますわ。見たいな感じですよね...。(でも、ざっとまとまってるのがなかったから!)
おまけとして。後は、プロパティにつける属性なんかがあったりします。
属性とはなんぞや? という方は XmlElement とかでggると幸せになれるかもです。
ちなみに初投稿。お目汚し失礼しました('ω')ノ