Hor*_*ter 9 c# deserialization c#-4.0
有没有办法找出对象属性是否作为DeSerialization过程的一部分被调用(例如,由XmlSerializationReaderXXX
).
背景:典型情况是在这种情况下禁用事件和复杂操作,直到初始化完成.
我发现的一种方法是"解释"堆栈并查看是否触发了呼叫 XmlSerializationReaderXXX
,这不是那么优雅恕我直言.有更好的吗?
public SomeClass SomeProperty
{
get { ..... }
set
{
this._somePropertyValue = value;
this.DoSomeMoreStuff(); // Do not do this during DeSerialization
}
}
Run Code Online (Sandbox Code Playgroud)
- 更新 -
正如Salvatore所提到的,在某种程度上类似于你是如何通过XML序列化加载的?
我有一个可能的解决方案。
public class xxx
{
private int myValue;
[XmlElement("MyProperty")]
public int MyPropertyForSerialization
{
get { return this.myValue; }
set
{
Console.WriteLine("DESERIALIZED");
this.myValue = value;
}
}
[XmlIgnore]
public int MyProperty
{
get { return this.myValue; }
set
{
Console.WriteLine("NORMAL");
this.myValue = value;
}
}
}
class Program
{
static void Main(string[] args)
{
xxx instance = new xxx();
instance.MyProperty = 100; // This should print "NORMAL"
// We serialize
var serializer = new XmlSerializer(typeof(xxx));
var memoryStream = new MemoryStream();
serializer.Serialize(memoryStream, instance);
// Let's print our XML so we understand what's going on.
memoryStream.Position = 0;
var reader = new StreamReader(memoryStream);
Console.WriteLine(reader.ReadToEnd());
// Now we deserialize
memoryStream.Position = 0;
var deserialized = serializer.Deserialize(memoryStream) as xxx; // This should print DESERIALIZED
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
技巧是使用 XmlIgnore,它将强制 xml 序列化程序忽略我们的属性,然后我们使用 XmlElement 使用我们想要的属性名称重命名该属性以进行序列化。
这种技术的问题在于,您必须公开公共属性以进行序列化,并且在某种程度上是不好的,因为它实际上可以被每个人调用。不幸的是,如果该成员是私有的,它将不起作用。
它可以工作,并不完全干净,但是线程安全并且不依赖任何标志。
另一种可能性是使用类似 Memento 模式的东西。使用相同的技巧,您可以添加一个名为 Memento 的属性,该属性返回另一个包含仅适合序列化的属性的对象,它可以使事情变得更干净。
您是否想过不改变方法并使用 DataContractSerializer?它功能更强大并且可以生成纯 XML。它支持OnDeserializationCallback机制。