【问题标题】:How do you serialize an unmodifiable class that contains an interface?如何序列化包含接口的不可修改类?
【发布时间】:2013-01-15 20:27:38
【问题描述】:

我正在尝试序列化包含接口的对象。但是,接口不能序列化。通常,我会使用 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完成相同的事情标记元素

我想到了一些解决方案,例如使用反射动态生成一个包含与要序列化的类相同的所有成员的类,执行某种类型的深度复制,然后对其进行序列化。但是,我很想知道是否有任何更简单的方法来完成这个序列化任务,而不是去类生成反射路由。

【问题讨论】:

  • 既然你使用的是XmlSerializer,你的意思是[XmlIgnore],而不是[NonSerialized],对吧?
  • 正确,对于这个特定的例子。我使用 [NonSerialized] 只是为了说明我要完成的工作。是的,[XmlIgnore] 会在这个例子中完成同样的事情。

标签: c# serialization interface nonserializedattribute


【解决方案1】:

如果现有类型的序列化变得复杂,最好的选择是总是:创建一个单独的 DTO 模型 - 它看起来有点类似于您的域实体,但仅存在可以很好地与序列化配合使用——通常非常简单(无参数构造函数、基本访问器、无验证等)。然后在它们之间映射。否则,您将玩打地鼠游戏,为它不喜欢的类型配置序列化程序。

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

【讨论】:

  • 谢谢!我可能会选择第一个选项。
【解决方案2】:

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

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

【讨论】:

  • 在这种情况下,它将实现 IXmlSerializable,这实际上比实现 ISerializable 要复杂得多。另外,如果您不控制类型,则无法实现此功能。
  • @MarcGravell,我建议他创建一个新的包装器类型,使用它他当然可以实现接口。
  • 我很抱歉,是的,这会起作用 - 但 IXmlSerializable 仍然是绝对的猪。一个简单的 DTO 并行模型可能更简单且不易出错。
猜你喜欢
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多