自动反序列化后执行

本文关键字:执行 反序列化 | 更新日期: 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是用AB计算的,没有序列化。假设我不想在访问器中动态地计算Sum。如何预算Sum ?自然地,首先调用构造函数,这意味着稍后不会赋值A和B,因此还不能计算Sum。是否有某种后反序列化或后实例化之类的东西,我可以使用,以便在一步中完全创建对象?我只是不希望我的对象永远处于不完整和无效的状态。

自动反序列化后执行

我想你是想问别的问题。这个用例不能证明您所要求的解决方案的复杂性。

如果这是用例:

  1. 动态计算。把Sum变成一个方法。
  2. 如果您担心开销,请使用后备字段。

if (_alreadyCalculated) 
{
    return _sum;
}
_sum = A+B;
_alreadyCalculated = true;
return _sum;

我认为你正在寻找OnDeserializedAttribute,该属性标记一个方法需要在反序列化对象后调用

EDIT——遗漏XmlSerializer部分....

最好的办法是在A和B的setter方法中重新计算sum

或者你可以让Sum getter使用Lazy

您应该使用常规属性并在AB的设置器中重新计算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();