从 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
,您可以确保它永远不会被永久遗留。
我想对使用 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
,您可以确保它永远不会被永久遗留。