8

シリアライゼーション/デシリアライゼーション手法を使用します。BinaryFormatter クラス。新しいアセンブリが作成されるたびに、BinaryFormatter は、クラス構造が同じであってもバイナリ データを逆シリアル化できませんが、アセンブリのバージョンは異なります。クラス構造が変更されていない場合、アセンブリのバージョンをチェックせずにバイナリ バッファを逆シリアル化することは可能ですか?

4

3 に答える 3

8

これを試して:

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        return Type.GetType(String.Format("{0}, {1}", typeName, Assembly.GetExecutingAssembly().FullName));
    }
}
formatter.Binder = new CurrentAssemblyDeserializationBinder();
formatter.Deserialize(inStream);

追加されたスレッド ポスター:

はい、動作します。System.Generic またはバイナリ データ内の他の Lib のいずれかのタイプが存在するかどうかを確認してから、それらを変更せずに渡す必要があります。"ResizableControls" - 古いアセンブリ ライブラリの名前、"EntityLib" - 新しいアセンブリ名。また、バージョン番号も必要に応じて置き換えられます。

public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        string name;
        if (assemblyName.Contains("ResizableControl"))
        {
            name = Assembly.GetAssembly(typeof(EntityLib.Pattern)).ToString();
        }
        else
        {
            name = assemblyName;
        }
        return Type.GetType(String.Format("{0}, {1}",
            typeName.Replace("ResizableControl", "EntityLib"), name));
    }
}

ありがとう、それはまさに私が必要としていたものです。

于 2011-08-22T23:07:53.940 に答える
6

それは固有のものBinaryFormatterです。それを回避するためにできる高度な方法がいくつかありますが (サロゲートなどを使用)、簡単ではないので、正直にお勧めしません。

コントラクトベースのシリアライザーを検討することを強くお勧めします。例えば:

  • XmlSerializer
  • DataContractSerializer(しかしそうではない NetDataContractSerializer
  • プロトブフネット

(後者の方がはるかに効率的な出力が得られ、意図的にいくつかのバージョン管理の問題を回避できるため、私は後者に偏っています)

これらすべての場合において、データ ストレージには (少なくとも既定の設定では)型の知識は含まれません。ただし、名前で暗示されているか、または指定されている (通常は属性で) コントラクトは除きます。

于 2011-08-22T21:57:09.890 に答える
1

これは BinaryFormatter の既知の問題だと思います-これは、SerializationBinder でロードするタイプを制御できる解決策です-リンクはコードとこれを使用する方法の例を提供します(ほとんどすべての.net言語で)

于 2011-08-22T21:53:33.477 に答える