- PR -

XML シリアル化について

投稿者投稿内容
Pluto
常連さん
会議室デビュー日: 2002/07/01
投稿数: 40
投稿日時: 2006-04-21 03:23
IDictionary を実装するクラス (HashTable や Dictionary 等) を XML シリアル化する場合、どのようしたらよいのでしょうか?(できれば、ISerializable インターフェイスを使用して)

MSDN では、「IDictionary を実装するオブジェクトをシリアル化する必要があるなら、独自のシリアル化機能を実装しなければなりません。」 と記されていましたが、その 「独自のシリアル化機能」 というのが分かりませんでした。

 http://www.microsoft.com/japan/msdn/enterprise/pag/scalenethowto01.asp

どなたか、ご教示下さいますようお願い致します。

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-04-21 06:04
Key の列挙をぐるぐる回して、Value にアクセスすればいいと思うんですけど、そういうことじゃない?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-04-21 23:21
っていうか、HashTable なら、ISerializable インターフェイスを実装しているから、そのまま使えるやん。
Pluto
常連さん
会議室デビュー日: 2002/07/01
投稿数: 40
投稿日時: 2006-04-22 00:24
Jitta さん、ご返答有難うございます。

また、当方のご返信が遅くなりすみませんでした。

引用:

っていうか、HashTable なら、ISerializable インターフェイスを実装しているから、そのまま使えるやん。



仰るとおり、HashTable や Dictionary クラスには、確かに ISerializable インターフェイスは実装されているのですが、やはり、これらを XML シリアル化することはできませんでした(MSDN に記載されているとおり...?)。

この ISerializable インターフェイスでは、やはり XML シリアル化はできないということでしょうか?(バイナリ シリアル化はできる...?)
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-04-22 01:25
ほんとだ。確かに例外出ますね。Dictionary<string, string>で確認。

それなら,一旦シリアライズ可能な型に変換してからシリアライズしてやるとかでどうでしょう?
後は,Jittaさんのおっしゃってるような方法とか。

独自のシリアル化昨日っていうのは,そのままじゃシリアル化できないから自分で頑張ってくれってことだと思います。
Pluto
常連さん
会議室デビュー日: 2002/07/01
投稿数: 40
投稿日時: 2006-04-22 01:47
Kazuki さん、夜分遅くにご返答有難うございます。

Dictionary クラスをシリアライズすることは、やはり出来ないですよね...
(ちなみに、XML シリアル化、バイナリ シリアル化のどちらを実行されたのでしょうか?)

独自のシリアル化というのも、Jitta さんの仰るとおり、シリアライズ(およびデシリアライズ)することが可能な型に変換するコーディングを行うということになり...

でも、そうすると、ここで実装されている ISerializable インターフェイスって、何なのでしょう...?
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2006-04-22 02:19
何で実装されてるんでしょうね?
私にはわからないです…。

とりあえず自分でやるとしたら逃げとして
IDictionary <-> IListに変換してくれるようなメソッドを用意して
IListに変換してからシリアライズします。
デシリアライズは逆の手順でやります。

とりあえず変換メソッド
コード:
  // IDictionary -> IList
  public static IList<Entry<TKey, TValue>> Convert<TKey, TValue>(
    IDictionary<TKey, TValue> dict)
  {
    IList<Entry<TKey, TValue>> ret = new List<Entry<TKey, TValue>>();
    foreach(TKey key in dict.Keys)
    {
      ret.Add(EntryFactory.Create(key, dict[key]));
    }
    return ret;
  }
  
  // IList -> IDictionary
  public static IDictionary<TKey, TValue> Convert<TKey, TValue>(
    IList<Entry<TKey, TValue>> list)
  {
    IDictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>();
    foreach (Entry<TKey, TValue> entry in list)
    {
      ret.Add(entry.Key, entry.Value);
    }
    return ret;
  }
 
  // keyとvalueのペア
  [Serializable]
  public class Entry<TKey, TValue>
  {

    private TKey key;

    public TKey Key
    {
      get { return key; }
      set { key = value; }
    }

    private TValue value_;

    public TValue Value
    {
      get { return value_; }
      set { value_ = value; }
    }
  }

  public static class EntryFactory
  {
    // Entryを作る時にめんどいのでお助け用生成メソッド
    public static Entry<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value)
    {
      Entry<TKey, TValue> entry = new Entry<TKey, TValue>();
      entry.Key = key;
      entry.Value = value;
      return entry;
    }
  }



ひょっとしたらDictionaryを素直にシリアライズする手があるかもしれないです
詳しい方いたらお願いします。
Pluto
常連さん
会議室デビュー日: 2002/07/01
投稿数: 40
投稿日時: 2006-04-22 02:30
Kazuki さん、夜遅くまでご返答いただき有難うございます。

Dictionary クラスをシリアライズ(およびデシリアライズ)を行う場合は、Kazuki さんのサンプルコードのような、「独自のシリアル化機能」で実現するしかないんですかね...

Kazuki さんの仰るとおり、Dictionary クラスに実装されている ISerializable インターフェイスを利用して、素直にシリアライズしたいものですが...
(何だか、ちょっと悔しいですね...)

スキルアップ/キャリアアップ(JOB@IT)