【问题标题】:Change the name of the class being serialized in .Net?更改.Net 中被序列化的类的名称?
【发布时间】:2010-02-10 12:41:03
【问题描述】:

我可以通过使用SerializationBinder 并覆盖BindToType 方法来映射传入的类名称,但我发现无法在序列化过程中更改类的名称。有可能吗??

编辑:

我指的是使用System.Runtime.Serialization 的序列化,而不是System.Xml.Serialization

谢谢!

【问题讨论】:

  • 你能告诉我你为什么要这样做吗?我经常发现,如果我想要做的事情没有功能/方法,那么我错过了一个更简单的解决方案,或者我只是想做一些奇怪的事情。
  • 我想这样做是为了使序列化和反序列化的过程独立于类名,这样如果我重命名类,或者更改类的命名空间,序列化和反序列化就不会完全改变。
  • 您执行的是什么类型的序列化?二进制? Xml?其他?
  • @silky:它是使用格式化程序的序列化类型,而不是 Xml。
  • @Miguel 是否可以切换到 XML?这将使您的生活变得更加轻松。二进制序列化方法不是用来处理对您的对象模型的更改。

标签: c# .net serialization


【解决方案1】:

我不确定我是否关注你,但你可以使用 XmlTypeAttribute。然后,您可以通过反射轻松检索其值。

[XmlType(Namespace = "myNamespaceThatWontChange",
TypeName = "myClassThatWontChange")]
public class Person
{
   public string Name;
}

看看这个:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmltypeattribute%28VS.100%29.aspx

【讨论】:

  • 但是这是XmlSerialization,我说的是使用SerializableAttribute和ISerializable接口的序列化。
  • Islam Ibrahim 的答案是“那个”答案(据我所知)。
【解决方案2】:

我发现我可以使用GetObjectData函数中的SerializationInfo对象,并更改AssemblyNameFullTypeName属性,这样当我反序列化时我可以使用SerializationBinder进行映射自定义程序集和类型名称恢复为有效类型。这是一个示例:

可序列化类:

[Serializable]
class MyCustomClass : ISerializable
{
    string _field;
    void MyCustomClass(SerializationInfo info, StreamingContext context)
    {
        this._field = info.GetString("PropertyName");
    }
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AssemblyName = "MyCustomAssemblyIdentifier";
        info.FullTypeName = "MyCustomTypeIdentifier";
        info.AddValue("PropertyName", this._field);
    }
}

序列化绑定器:

public class MyBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        if (assemblyName == "MyCustomAssemblyIdentifier")
            if (typeName == "MyCustomTypeIdentifier")
                return typeof();
        return null;
    }
}

序列化代码:

var fs = GetStream();
BinaryFormatter f = new BinaryFormatter();
f.Binder = new MyBinder();
var obj = (MyCustomClass)f.Deserialize(fs);

反序列化代码:

var fs = GetStream();
MyCustomClass obj = GetObjectToSerialize();
BinaryFormatter f = new BinaryFormatter();
f.Deserialize(fs, obj);

【讨论】:

    【解决方案3】:

    你可以用属性做到这一点:

    [System.Xml.Serialization.XmlRoot("xmlName")]
    public Class ClassName
    {
    }
    

    【讨论】:

      【解决方案4】:

      看看使用代理+代理选择器。这与反序列化的活页夹一起应该可以解决问题。

      【讨论】:

      • 这很有趣,但不是我想要的。我发现我可以使用GetObjectDataSerializationInfo 对象并同时更改AssemblyNameFullTypeName 属性。
      • 这很危险,因为您可能需要在不同的上下文中序列化实例。即层之间的数据传输、克隆、持久性等。如果您确实走这条路,请务必指定流式传输上下文。 (示例) formatter.Context = new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.CrossMachine);还要注意,您将被绑定到您为其命名项目的活页夹。
      猜你喜欢
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      相关资源
      最近更新 更多