Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化的触发器函数_C#_Serialization_Mono_Xml Serialization - Fatal编程技术网

C# 反序列化的触发器函数

C# 反序列化的触发器函数,c#,serialization,mono,xml-serialization,C#,Serialization,Mono,Xml Serialization,我有一个类,它有许多字段,这些字段通常是在构造函数中根据类中的其他数据计算出来的。它们没有序列化为XML,因为对其余数据的任何更改都可能需要重新计算 有什么方法可以设置反序列化时触发的函数调用吗?您所描述的是 XmlSerializer不支持序列化回调方法(至少在MS.NET中不支持;mono可能不同)。根据需要,您可以尝试使用支持序列化回调的DataContractSerializer(与许多其他序列化程序一样)。否则,最好的方法可能是拥有自己的公共方法,手动调用 另一个选项是手动实现IXml

我有一个类,它有许多字段,这些字段通常是在构造函数中根据类中的其他数据计算出来的。它们没有序列化为XML,因为对其余数据的任何更改都可能需要重新计算


有什么方法可以设置反序列化时触发的函数调用吗?

您所描述的是

XmlSerializer
不支持序列化回调方法(至少在MS.NET中不支持;mono可能不同)。根据需要,您可以尝试使用支持序列化回调的
DataContractSerializer
(与许多其他序列化程序一样)。否则,最好的方法可能是拥有自己的公共方法,手动调用

另一个选项是手动实现
IXmlSerializable
,但这很难。

--编辑:

刚刚确认,正如下面的评论员所说,xml序列化过程没有命中“OnDeserialized”属性声明的方法。真可惜

--以前的答复:

是的,的确如此,看一看

特别值得关注的是所讨论的
OnDeserialized
属性


值得注意的是,根据所使用的序列化方法(我认为),将调用no-arg构造函数。显然,这将在设置任何其他设置之前发生。因此,它可能并不完全有用。

因为可以进行XML序列化的对象需要一个公共的无参数构造函数,所以即使在进行XML序列化之前,类设计中似乎也存在漏洞

就我个人而言,我会对这些字段进行懒散的计算。无论是否计算了字段,都在类中存储一个标志,并在计算中使用的任何属性发生更改时,将该字段设置为表示“过期”的值。然后,在返回计算值的属性中,检查是否需要在返回值之前重新计算

无论XML序列化与否,这都将起作用

例如:

[XmlType("test")]
public class TestClass
{
    private int _A;
    private int? _B;

    public TestClass()
        : this(0)
    {
    }

    public TestClass(int a)
    {
        _A = a;
    }

    [XmlAttribute("a")]
    public int A
    {
        get { return _A; }
        set { _A = value; _B = null; }
    }

    [XmlIgnore]
    public int B
    {
        get { if (_B == null) Recalculate(); return _B; }
        set { _B = value; }
    }

    private void Recalculate()
    {
        _B = _A + 1;
    }
}

您可以实现接口

…这不是
XmlSerializer所使用的-p@Marc ... 是的,但说真的,你知道为什么吗?可能是因为序列化回调是在2.0中添加的,而XmlSerializer是从旧的1.1天开始的。从理论上讲,它可能会对现有代码引入突破性的更改(尽管我想他们可能会在
[XmlType]
中明确表示“UseCallbacks=true”)。不过,最有可能的情况是,他们没有时间为需要它的有限用户充分评估可能的影响、实施它、调试它等等。@Tom-确实如此。实际上,我有点想看看我是否可以调整protobuf net,使它能够写入
XmlWriter
,因为它确实支持回调之类的东西。目前唯一的输出是二进制的(“协议缓冲区”二进制格式),但我想我可以让它做一些更灵活的事情。。。xml、json等。我确实有一个无参数构造函数,但它并没有真正做任何有用的事情,因为还没有数据。我还可以想象它会在反序列化之前被调用,所以我在那里做不了什么。不过我会考虑你的建议。请看我对@silky的评论
XmlSerializer
不支持序列化回调(不通过接口,也不通过属性)
IDeserializationCallback
不被XmlSerializer使用这是我一直在寻找的。令人沮丧的是,它不适用于XML。我想我只需要记下手动调用该方法。这样更容易。