3

我正在尝试序列化包含接口的对象。但是,接口不能序列化。通常,我会使用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

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.

4

2 回答 2

4

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). 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. 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. Frankly, I advise against this approach.

于 2013-01-15T20:36:14.640 回答
1

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. 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.

于 2013-01-15T20:37:30.523 回答