如何序列化包含接口的不可修改的类?

时间:2013-01-15 20:27:39

标签: c# serialization interface nonserializedattribute

我正在尝试序列化包含接口的对象。但是,接口无法序列化。通常,我会使用类似NonSerialized标记的内容,但我无法弄清楚如何将此属性应用于我无法修改的类,例如预定义的.NET类之一(例如:System.Diagnostics.Process )。

例如,请考虑以下代码:

using System.Diagnostics
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            XmlSerializer x = new XmlSerializer(typeof(Process));
        }
        catch (Exception e)
        {
            Console.WriteLine(e.InnerException.InnerException.Message);
        }
    }
}

这将打印以下结果:

Cannot serialize member System.ComponentModel.Component.Site of type System.ComponentModel.ISite because it is an interface.

有没有办法在我无法修改的类中执行以下任何,例如系统类?

  1. 在序列化期间有选择地忽略子元素,以便子元素不会被序列化
  2. 使用与NonSerialized
  3. 相同的内容标记元素

    我想过一些解决方案,比如使用反射来动态生成一个类,该类包含与要序列化的类相同的所有成员,执行某种类型的深层复制以及序列化。但是,我很想知道是否有更简单的方法来完成这个序列化任务,而不是去生成反射路径的类。

2 个答案:

答案 0 :(得分:3)

如果现有类型的序列化变得复杂,最好的选择是始终:创建一个单独的DTO模型 - 看起来与您的域实体类似,但仅限于存在与序列化很好地协作 - 通常非常简单(无参数构造函数,基本访问器,无验证等)。然后在他们之间映射。否则,你将会玩一个不太喜欢的类型的序列化器来玩游戏。

如果你希望使用XmlSerializer进行游戏:你可以创建一个XmlAttributeOverrides实例,为你的特定类型手动配置它(添加属性实例),并将其传递给XmlSerializer构造函数。但这很丑陋,非常繁琐,你必须必须缓存并重新使用序列化程序实例(如果使用构造函数的重载,则不适用正常的自动程序集缓存/重用)。您可以(从XmlAttributeOverrides实例)获取每个类型或每个成员的XmlAttributes实例,然后根据需要获取XmlIgnore属性为true。坦率地说,我建议不要这样做。

答案 1 :(得分:1)

通常,您序列化自己实现的对象,这样可以在这样的实例中完全控制。我将创建一个实现ISerializable的包装器对象,并在其构造函数中接受一个Process对象。这样,您就可以控制自己序列化的字段。

话虽如此,序列化可执行流程似乎并不可行。我想你会想要序列化一个包含行数据的对象,然后在线路的另一端消费(在反序列化时)。 Process类表示系统中正在运行的代码实例,因此想要序列化它似乎很奇怪。