从 Xml 反序列化对象后执行自定义类型的代码 [英] Execute code to custom type after deserializing an object from Xml
问题描述
我想对使用 XmlSerializer.Deserialize 创建的 CustomType 的所有实例进行一些操作
I want do some manipulation on all instances of a CustomType that got created with an XmlSerializer.Deserialize
最好的方法是作为构造函数传入,但PostSerialization"可以正常工作.在此示例中,我需要根据 XmlSerializer 上下文将对象传递给我的 CustomType.
The best way would be to pass in as a constructor, but "PostSerialization" would work just fine. In this example, I need to pass in an object to my CustomType based from the XmlSerializer context.
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.
XmlAttributeOverrides is a good idea, but "MyType" is quite complex, I can't go through all the possible XmlElement to custom create the CustomType.
推荐答案
您可以将 Object somethingImportant
设为线程静态变量,并在非 null 时在构造函数中使用它,如下所示:
You could make the Object somethingImportant
a thread-static variable, and use it in the constructor when non-null, like so:
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)
{
}
}
然后在反序列化时设置它:
Then set it when deserializing like so:
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
,您可以确保它永远不会被永久遗留.
By publicly setting the deserializationObject
only within the disposable wrapper you ensure it's never left around permanently.
这篇关于从 Xml 反序列化对象后执行自定义类型的代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!