3

我正在使用将对象序列化为 XML System.Xml.Serialization,这需要我有无参数的构造函数。

因此,我尝试使用对象初始化语法将值分配给某些属性,然后在将对象序列化为 XML 之前根据需要使用构造函数逻辑来格式化这些值。

我的问题是构造函数在属性被赋值之前运行。一个简化的例子如下:

class Program
{
    static void Main(string[] args)
    {
        Foo myFoo = new Foo() { HelloWorld = "Beer", HelloWorldAgain = "More beer" };

        Console.WriteLine(myFoo.HelloWorld);
        Console.WriteLine(myFoo.HelloWorldAgain);

        Console.ReadLine();
    }
}

public class Foo : Bar
{
    public string HelloWorld { get; set; }

    public Foo()
    {
        Console.WriteLine("Foo Was Initialized");
        Console.WriteLine(HelloWorld);
    }
}

public abstract class Bar
{
    public string HelloWorldAgain { get; set; }

    public Bar()
    {
        Console.WriteLine("Bar was initialized");
        Console.WriteLine(HelloWorldAgain);
    }
}

这将产生以下输出:

输出

如您所见,构造函数逻辑运行,然后属性被赋值。我需要这个以相反的方式工作。

这可能吗?

4

4 回答 4

6

序列化要求你有一个无参数的构造函数,但并不限制你使用那个构造函数。

保留无参数构造函数以进行反序列化,但添加另一个构造函数,当您需要在代码中实例化类时,该构造函数接受您的值并执行所需的初始化。

对象初始化语法只是构造后设置属性的简写。

于 2012-06-20T18:13:30.823 回答
5

不,对象初始化语法只是一个捷径。当你写:

Foo foo = new Foo { HelloWorld  = "Beer" };

编译器只是将其重写为与您编写时非常接近的内容:

Foo foo = new Foo();
foo.HelloWorld  = "Beer";

如果需要参数才能使对象存在,则应将它们作为参数放入构造函数中。

于 2012-06-20T18:11:27.057 回答
2

不,这是不可能的,因为为了能够初始化对象的属性,对象已经存在。它的存在是由 ctor在所有其他东西之前运行来保证的。

如果我们谈论“不运行默认构造函数”,就像一个概念性问题。您可以通过使用static属性来做到这一点。在这种情况下 Foo() 将不会被调用。但这自然不在当前的问题主题范围内。

于 2012-06-20T18:09:54.227 回答
1

可以说,语法具有欺骗性。这里发生了什么?

var myFoo = new Foo();
myFoo.HelloWorld = "Beer";
myFoo.HelloWorldAgain = "MoreBeer";

就是这样,我害怕。在构造函数运行之前根本不可能初始化属性。构造函数是在为对象分配内存并将默认值分配给字段之后“发生”的第一件事。

顺便说一句,您不需要使用对象初始化语法的括号。这同样好(但更具欺骗性):

var myFoo = new Foo { HelloWorld = "Beer", HelloWorldAgain = "MoreBeer" };

查看您的问题,看起来您正在尝试做的事情(在序列化之前修改属性)不属于构造函数。

于 2012-06-20T18:14:11.220 回答