0

如果类型名称发生更改,我正在使用 aSerializationBinder绑定到当前类型。因此,我有一个将旧类型名称绑定到新名称的字典。

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 回答
0

您不需要任何复杂的程序。假设您要反序列化这样的类型名称:

System.Collections.Generic.List`1[[Myclass, MyNameSpace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]

简单地说,处理AppDomain.AssemblyResolve事件,然后调用Type.GetType具有上述类型名称的方法。它会引发事件,在那里,您可以返回任何您想要的程序集。

于 2018-11-29T10:58:27.247 回答