虚飾の王

2009-09-09 みにー

実家に行ったら娘の誕生日プレゼント用のミニーさんが鎮座していた。

娘と同じぐらいの大きさだった。

[][]C#::XmlSerializerとXmlAttributeOverrides C#::XmlSerializerとXmlAttributeOverridesを含むブックマーク

XmlSerializerのコンストラクタにXmlAttributeOverridesを渡すとシリアライズ制御用属性をあと付けできる。これを使うことで、ライブラリ考慮されていない新規の派生クラスを追加するとか、特定の環境向けに要素名などを変更することが出来る。

ところで、MSDNには以下のような記述がある。

動的に生成されるアセンブリ

パフォーマンスを向上するために、XML シリアルインフラストラクチャでは、指定した型のシリアル化と逆シリアル化を行うアセンブリが動的に生成されます。それらのアセンブリインフラストラクチャによって検索および再利用されます。この動作は、次のコンストラクタを使用するときにだけ発生します。

System.Xml.Serialization.XmlSerializer(Type)

System.Xml.Serialization.XmlSerializer(Type,String)

他のコンストラクタを使用すると、同じアセンブリの複数のバージョンが生成され、アンロードされません。その結果、メモリリークが発生し、パフォーマンスも低下します。最も簡単な解決方法は、上で挙げた 2 つのコンストラクタのいずれかを使用することです。それ以外の場合は、アセンブリを Hashtable にキャッシュする必要があります。これを次の例に示します。

つまり、XmlAttributeOverridesを使ったインスタンスを生成するごとにアセンブリを生成して開放しないということか。ということは、XmlAttributeOverridesを使って生成するXmlSerializerのオブジェクトはどこか別のところに控えておいて、必要になったらそれを再利用する、という方式を取らなければならない、ということ。

引用部にある「Hashtableにキャッシュする」というのは、次のようなクラスを作ってオーバーライドしたXmlSerializerをSingleton化するというのとほぼ同じ意味

public class OverriddenCLASSSerialzier {
  private static XmlSerializer ser;
  public static Instance{
    get { 
      if(ser == null) startup();
      return ser;
    }
  }
  private void startup(){
    var ovrd = new XmlAttributeOverrides();
    //ここにオーバーライドの設定を入れる
    ser = new XmlSerializer(typeof(CLASS), ovrd);
  }
}
//usage:
//  CLASS obj;
//  OverriddenCLASSSerialzier.Instance.Serialzie(stream, obj);

せめて明示的にアンロードできる方法があればいいのに。

[]電柱のないニュータウン 電柱のないニュータウンを含むブックマーク

( ゜Д゜)<ま、電気も来てませんけどね

Connection: close