【问题标题】:Execute code to custom type after deserializing an object from Xml从 Xml 反序列化对象后执行自定义类型的代码
【发布时间】:2015-04-04 04:54:46
【问题描述】:

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

【问题讨论】:

  • CustomTypeMyType是什么关系?
  • @CoderDennis MyType 中某个地方的一些孩子的孩子。示例类 MyType { public CustomType A {get;set;} },但更复杂。 (见我问题的最后一句话)
  • 好的,但我仍然不知道您在寻找什么。如果您不与我们分享任何复杂性,我们将无法帮助您解决复杂性。
  • 其实,你能不能把Object somethingImportantthread-static,在无参构造函数中非空时使用?
  • @dbc 这是一个丑陋/伟大的解决方案 dbc。您能否将其作为以下解决方案提出。我会采用那个解决方案。

标签: c# xml xmlserializer


【解决方案1】:

您可以将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,您可以确保它永远不会被永久保留。

【讨论】:

  • 您使用了完整的示例!谢谢!我的大部分字段都是私有/内部的,所以我简化了一点。但是这个例子很棒,谢谢。
猜你喜欢
  • 2021-05-03
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多