0

SerializationBinderタイプ名が変更された場合に備えて、現在のタイプにバインドするためにa を使用しています。したがって、古い型名を新しい名前にバインドする辞書があります。

dict.Add("Old.Namespace.OldTypeName", "New.Namespace.NewName");

この辞書を使用して、 のType BindToType(string assemblyName, string typeName)メソッドで型を取得できますSerializationBinder。この型がジェネリック型で使用されている場合、ジェネリックの新しい型も見つけなければなりません。この回答は、 に対してこれを行う方法を説明しましたList<T>。あらゆる種類のジェネリックの新しいタイプを取得するためにある種の正規表現を使用できるように、ジェネリック型名の標準化された形式があるかどうか疑問に思っています。

public class TypeDictionary
{
    private Dictionary<string, Type> bindings_ =
        new Dictionary<string, Type>();

    public void AddBinding(string oldTypeString, Type newType)
    {
        bindings_.Add(oldTypeString, newType);
    }

    public Type NewType(string oldTypeString)
    {
        // How should this be implemented:
        if (IsGeneric(oldTypeString))
            return NewGenericType(oldTypeString);

        Type newType;
        if (bindings_.TryGetValue(oldTypeString, out newType))
            return newType;
        return null;
    }
 }

私がこれまでに見たほとんどの文字列はList<T>このようなものです

 Namespace.TypeName`1[[MyAssembly.MyClass, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

"[[MyAssembly.MyClass,"ジェネリック型を検出するために探すだけで保存できますか?

4

3 に答える 3

1

総称型のフルネームには、バックティック文字( `)、型引数の数を指定する数字、各型引数を含む角括弧(おそらく追加の角括弧内)が含まれます。

だから次List<String>のように書かれています

  List`1[[String]]

Dictionary<String, Object>ように

  Dictionary`2[[String],[Object]]

Func<String, Object, Guid>ように

  Func`3[[String],[Object],[Guid]]

ただし、完全な名前空間はジェネリック型に指定され、完全な名前空間、アセンブリ、バージョン、カルチャ、および公開鍵トークンは各型引数に指定されます。

一方、非ジェネリック型のフルネームには、バックトリックも角括弧も含まれていません。たぶん、これを念頭に置いて正規表現を書くことができますか?

PS!oldType.ToString()代わりに使用するとoldType.FullName、アセンブリ、カルチャなどを含まない、やや短い文字列が得られます。

于 2012-05-07T13:12:41.320 に答える
0

MyClassおそらく、それらが他のクラスのジェネリック型パラメーターであるかどうかにかかわらず、へのすべての参照を置き換えたいと思うでしょう。

そのため、型名文字列内の任意の場所で型名を探す必要があります。

辞書内のすべての型名を置き換えると、 Type.GetType( string typeName )に渡すことができる新しい文字列が得られます。Typeこれにより、から返すことができる新しいインスタンスが得られますBindToType

置換する型自体がジェネリックである場合、少し注意が必要です。

于 2012-05-07T11:22:11.863 に答える