自动反序列化后执行
本文关键字:执行 反序列化 | 更新日期: 2023-09-27 18:08:36
假设c#中有一个简单类:
[Serializable]
public class MyClass
{
public int A { get; set; }
public int B { get; set; }
[XmlIgnore]
public int Sum { get; }
}
这是从一个包含a和b值的简单XML文件反序列化的。然而,Sum
是用A
和B
计算的,没有序列化。假设我不想在访问器中动态地计算Sum。如何预算Sum
?自然地,首先调用构造函数,这意味着稍后不会赋值A和B,因此还不能计算Sum。是否有某种后反序列化或后实例化之类的东西,我可以使用,以便在一步中完全创建对象?我只是不希望我的对象永远处于不完整和无效的状态。
我想你是想问别的问题。这个用例不能证明您所要求的解决方案的复杂性。
如果这是用例:
- 动态计算。把Sum变成一个方法。
- 如果您担心开销,请使用后备字段。
。
if (_alreadyCalculated)
{
return _sum;
}
_sum = A+B;
_alreadyCalculated = true;
return _sum;
我认为你正在寻找OnDeserializedAttribute,该属性标记一个方法需要在反序列化对象后调用
EDIT——遗漏XmlSerializer
部分....
最好的办法是在A和B的setter方法中重新计算sum
或者你可以让Sum getter使用Lazy
您应该使用常规属性并在A
和B
的设置器中重新计算Sum
。
一种方法是自己修改序列化器。您可以使用SGen获取序列化器的代码,如下所示:
sgen /f /k /a:MyAssembly.dll
这将使XmlSerializer 'temp'文件留在当前目录中。将该代码添加到您的项目中并进行更改。
global::ConsoleApplication31.Foo Read2_Foo(bool isNullable, bool checkType) {
// ...
if (Reader.IsEmptyElement) {
Reader.Skip();
return Callback(o);
}
// ...
return Callback(o);
}
private T Callback<T>(T value) {
if (value is IDeserializationCallback)
((IDeserializationCallback)value).OnDeserialization(this);
return value;
}
然后,您可以在代码中直接实例化序列化器。你可以使用NRefactory(查找Read_*
方法并更改任何返回行)之类的东西来自动化此操作——如果你不这样做,你将有维护开销。示例用法:var ser = new FooSerializer();
using (var sr = new StringReader("<foo />"))
{
var foo = ser.Deserialize(sr);
}
Console.ReadLine();