简体   繁体   English

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

[英]How do you serialize an unmodifiable class that contains an interface?

I am trying to serialize an object that contains an interface. 我正在尝试序列化包含接口的对象。 However, interfaces cannot be serialized. 但是,接口无法序列化。 Normally, I would use something like the NonSerialized tag, but I cannot figure out how to apply this attribute to a class that I cannot modify, such as one of the predefined .NET classes (eg: System.Diagnostics.Process ). 通常,我会使用类似NonSerialized标记的东西,但我无法弄清楚如何将此属性应用于我无法修改的类,例如预定义的.NET类之一(例如: System.Diagnostics.Process )。

For example, consider the following code: 例如,请考虑以下代码:

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);
        }
    }
}

This prints the following result: 这将打印以下结果:

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

Is there a way to do any of the following in a class that I cannot modify , such as a system class? 有没有办法在我无法修改的类中执行以下任何操作,例如系统类?

  1. selectively ignore child elements during serialization, so that the child element does not get serialized at all 在序列化期间有选择地忽略子元素,以便子元素根本不会被序列化
  2. mark an element with something that accomplishes the same thing as NonSerialized 使用与NonSerialized完成相同的操作标记元素

I've thought of some solutions like using reflection to dynamically generate a class that contains all the same members as the class to be serialized, doing some type of deep copy, and serializing that. 我已经想到了一些解决方案,比如使用反射来动态生成一个类,该类包含与要序列化的类相同的所有成员,执行某种类型的深层复制以及序列化。 However, I'm curious to see if there is any simpler way to accomplish this serialization task other than going the class generating reflection route. 但是,我很想知道是否有更简单的方法来完成此序列化任务,而不是去生成反射路径的类。

If serialization of an existing type gets complicated, the best option is always : create a separate DTO model - that looks kinda similar to your domain entity, but which only exists to play nicely with serialization - usually very simple (parameterless constructors, basic accessors, no validation, etc). 如果现有类型的序列化变得复杂,最好的选择始终是:创建一个单独的DTO模型 - 看起来有点类似于您的域实体,但只存在与序列化很好地协作 - 通常非常简单(无参数构造函数,基本访问器,没有验证等)。 Then map between them. 然后在他们之间映射。 Otherwise, you'll be playing a game of whack-a-mole with configuring a serializer for a type it doesn't really like. 否则,你将会玩一个不太喜欢的类型的序列化器来玩游戏。

If you want a game of whack-a-mole with XmlSerializer: you can create an XmlAttributeOverrides instance, configure it by hand for your specific type (adding the attribute instances), and pass it into the XmlSerializer constructor. 如果你想要一个使用XmlSerializer的游戏:你可以创建一个XmlAttributeOverrides实例,手动为你的特定类型配置它(添加属性实例),并将它传递给XmlSerializer构造函数。 But this is ugly, quite fiddly, and you must must must cache and re-use the serializer instance (the normal automatic assembly cache/re-use doesn't apply if you use that overload of the constructor). 但这很丑陋,非常繁琐,你必须必须缓存并重新使用序列化程序实例(如果使用构造函数的重载,则不适用正常的自动程序集缓存/重用)。 You can obtain (from the XmlAttributeOverrides instance) an XmlAttributes instance per-type or per-member, and then the XmlIgnore property to true as necessary. 您可以(从XmlAttributeOverrides实例)获取每个类型或每个成员的XmlAttributes实例,然后根据需要获取XmlIgnore属性为true。 Frankly, I advise against this approach. 坦率地说,我建议反对这种做法。

Typically you serialize an object that you are implementing yourself which gives you full control in instances like this. 通常,您序列化自己实现的对象,这样可以在这样的实例中完全控制。 I would create a wrapper object that implements ISerializable and in its constructor accepts a Process object. 我将创建一个实现ISerializable的包装器对象,并在其构造函数中接受一个Process对象。 That way, you can control which fields are being serialized yourself. 这样,您可以控制自己序列化的字段。

Having said that, serializing a an executable process does not seem viable. 话虽如此,序列化可执行流程似乎并不可行。 I'd imagine you would want to serialize an object that contains row data that you then consumer over the other end of the wire (at the time of deserialization). 我想你会想要序列化一个包含行数据的对象,然后在线路的另一端消费(在反序列化时)。 The Process class represents a running instance of code in the system, so it seems strange to be wanting to serialize it. Process类表示系统中正在运行的代码实例,因此想要序列化它似乎很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM