XmlSerializer 调用的无参数构造函数的规则是什么 [英] What are the rules for the parameterless constructor invoked by XmlSerializer

查看:27
本文介绍了XmlSerializer 调用的无参数构造函数的规则是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在子标题XML 序列化注意事项"下在这个链接上它说...

Under the sub-heading "XML Serialization Considerations" at this link it says...

一个类必须有一个无参数的构造函数才能被序列化XmlSerializer.

A class must have a parameterless constructor to be serialized by XmlSerializer.

这实际上是一种误导.实际上,您不需要声明无参数构造函数(默认构造函数).stackoverflow.com 上的答案表明您不需要声明无参数构造函数,除非您声明了参数化构造函数.一旦声明了参数化构造函数,那么您还需要声明无参数构造函数.

This is actually misleading. In fact you do not need to declare a parameterless constructor (default constructor). Answers on stackoverflow.com indicate that you do not need to declare the parameterless constructor unless you declare a parameterized constructor. Once a parameterized constructor is declared then you need to also declare the parameterless constructor.

我对无参数构造函数语句块感兴趣.

I am interested in the parameterless constructor statement block.

我的测试程序表明,在一种情况下,将无参数构造函数留空是无害的,并且恢复成功.在另一种情况下,无参数构造函数中的成员数据分配似乎被恢复覆盖了.在另一种情况下,可以在无参数构造函数中扩充成员数据对象图,并且该扩充先于恢复的对象.也许规则是,如果成员数据是引用,如果引用为空,它将被恢复,但如果无参数构造函数语句块使其非空,那么恢复将增加该引用处的对象.我刚刚意识到规则是错误的,因为实际上字符串是一种引用类型,而我的测试显示字符串引用无法恢复.

My test program indicates that in one case it is harmless to leave the parameterless constructor empty and restoration is successful. In another case member data assignment in the parameterless constructor seems to be overwritten by the restoration. In another case a member data object graph can be augmented in the parameterless constructor and that augmentation precedes restored objects. Perhaps the rule is that if the member data is a reference it will be restored if the reference is null but if the parameterless constructor statement block makes it non-null then the restoration will augment the object at that reference. I just realized the rule is wrong because actually string is a reference type and my test shows a string reference does not survive restoration.

无参数构造函数语句块的规则是什么?(如果您知道记录在哪里,请发布链接.)

What are the rules for the parameterless constructor statement block? (If you know where this is documented then please post a link.)

public class BlobEmpty
{
    public string name;
    public List<int> list;
    internal BlobEmpty() 
    {
        // demonstrate that XmlSerializer does not require any content in the 
        // statement block of the parameterless constructor
        Console.Beep(); // this gets executed upon deserialization 
                        // but this statement block is essentially empty
        // ** note that I do not instantiate the list of int **
    }
    internal BlobEmpty(string name) 
    { 
        this.list = new List<int>(); 
        this.name = name; 
    }
}
public class BlobPopulate
{
    public string name;
    public List<int> list;
    internal BlobPopulate()
    {
        Console.Beep(); // this gets executed upon deserialization
        this.list = new List<int>(); // this object will survive the restoration
        this.list.Add(999); // this item will be in front of the restored items
        this.name = "garbage"; // this string will not survive the restoration
    }
    internal BlobPopulate(string name)
    {
        this.list = new List<int>();
        this.name = name;
    }
}

为了完整起见,这里是测试程序...

For the sake of completeness here is the test program...

private static void TestDeserialization0(string name, string fileName)
{
    var c = new BlobEmpty(name);
    c.list.Add(123); 
    c.list.Add(456);
    Serialize(c, fileName);
    var restored = (BlobEmpty)Deserialize(typeof(BlobEmpty), fileName);
    Debug.Assert(restored.name.Equals(name));
    Debug.Assert(restored.list.Count == 2);
    Debug.Assert(restored.list[0].Equals(123));
    Debug.Assert(restored.list[1].Equals(456));
}
private static void TestDeserialization1(string name, string fileName)
{
    var c = new BlobPopulate(name);
    c.list.Add(123);
    c.list.Add(456);
    Serialize(c, fileName);
    var restored = (BlobPopulate)Deserialize(typeof(BlobPopulate), fileName);
    Debug.Assert(restored.name.Equals(name));
    Debug.Assert(restored.list.Count == 3);
    Debug.Assert(restored.list[0].Equals(999));
    Debug.Assert(restored.list[1].Equals(123));
    Debug.Assert(restored.list[2].Equals(456));
}

推荐答案

这实际上是一种误导.实际上,您不需要声明无参数构造函数(默认构造函数).stackoverflow.com 上的回答表明您不需要声明无参数构造函数,除非您声明了参数化构造函数.一旦声明了参数化构造函数,那么您还需要声明无参数构造函数.

This is actually misleading. In fact you do not need to declare a parameterless constructor (default constructor). Answers on stackoverflow.com indicate that you do not need to declare the parameterless constructor unless you declare a parameterized constructor. Once a parameterized constructor is declared then you need to also declare the parameterless constructor.

这不是误导.在没有任何其他构造函数的情况下,C# 编译器会自动添加默认的无参数构造函数.它仍然是声明的,只是不是你声明的.

It's not misleading. Without any other constructors, the C# compiler automatically adds in the default parameter-less constructor. It's still declared, just not by you.

BlobEmpty 中,序列化程序将检查list 并看到它是null,因此它将实例化它.然后它会调用 Add 来插入新元素.

In BlobEmpty the serializer will check the list and sees it is null so it will instantiate it. Then it will call Add to insert the new elements.

BlobPopulate 中,序列化程序将获取list 并查看它不是null.它将在现有列表上调用 Add 以插入新元素.

In BlobPopulate the serializer will take list and see it is not null. It will call Add on the existing list to insert the new elements.

任何其他属性(不是 IEumerable)将始终被覆盖.

Any other properties (not IEumerable) will always be overwritten.

这篇关于XmlSerializer 调用的无参数构造函数的规则是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆