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

时间:2015-04-03 19:01:33

标签: c# xml xmlserializer

我想对使用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。

1 个答案:

答案 0 :(得分:1)

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

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,确保它永远不会永久留在身边。