从 Xml 反序列化对象后执行自定义类型的代码

Execute code to custom type after deserializing an object from Xml

我想对使用 XmlSerializer.Deserialize

创建的 CustomType 的所有实例进行一些操作

最好的方法是作为构造函数传入,但 "PostSerialization" 就可以了。 在此示例中,我需要将对象从 XmlSerializer 上下文传递到我的 CustomType。

public class CustomType : IXmlSerializable
{
    public CustomType()
        : this(null)
    {
    }

    public CustomType(Object somethingImportant)
    {
    }

    public void ReadXml(System.Xml.XmlReader reader) { ... }
    public void WriteXml(System.Xml.XmlWriter writer) { ... }
}

...

Object somethingImportant = 12345; // I need to pass this to *all* CustomType
var serializer = new XmlSerializer(typeof(MyType));
var reader = new StringReader(str);
return serializer.Deserialize(reader) as MyType;

XmlAttributeOverrides 是个好主意,但 "MyType" 相当复杂,我无法通过所有可能的 XmlElement 来自定义创建 CustomType。

您可以使 Object somethingImportant 成为线程静态变量,并在非空时在构造函数中使用它,如下所示:

public class CustomType 
{
    [ThreadStatic]
    static object deserializationObject;

    public static IDisposable SetDeserializationObject(object deserializationObject)
    {
        return new DeserializationObjectValue(deserializationObject);
    }

    sealed class DeserializationObjectValue : IDisposable
    {
        object oldValue;

        public DeserializationObjectValue(object value)
        {
            this.oldValue = deserializationObject;
            deserializationObject = value;
        }

        int disposed = 0;

        public void Dispose()
        {
            // Dispose of unmanaged resources.
            if (Interlocked.Exchange(ref disposed, 1) == 0)
            {
                Dispose(true);
            }                // Suppress finalization.  Since this class actually has no finalizer, this does nothing.
            GC.SuppressFinalize(this);
        }

        void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Free any other managed objects here.
                deserializationObject = oldValue;
                oldValue = null;
            }
        }
    }

    private CustomType(object deserializationObject)
    {
        if (deserializationObject != null)
        {
            // Handle as needed.
        }
    }

    public CustomType() : this(deserializationObject)
    {
    }
}

然后反序列化时这样设置:

        using (CustomType.SetDeserializationObject("this is a runtime value"))
        {
            var serializer = new XmlSerializer(typeof(MyType));
            var reader = new StringReader(str);
            var myType = serializer.Deserialize(reader) as MyType;
        }

通过仅在一次性包装内公开设置 deserializationObject,您可以确保它永远不会被永久遗留。