我可以使用对象初始化语法在构造函数运行之前为属性赋值吗?

时间:2012-06-20 18:07:56

标签: c# constructor initialization

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

因此,我尝试使用对象初始化语法为某些属性赋值,然后在将对象序列化为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);
    }
}

这导致以下输出:

Output

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

这可能吗?

4 个答案:

答案 0 :(得分:6)

序列化要求您拥有无参数构造函数,但不限制您使用该构造函数。

保持no-arg构造函数以进行反序列化,但添加另一个获取值的构造函数,并在需要在代码中实例化类时执行所需的初始化。

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

答案 1 :(得分:5)

没有。对象初始化语法只是一种快捷方式。当你写:

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

编译器只是将其重写为非常接近于写入时发生的事情:

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

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

答案 2 :(得分:2)

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

如果我们正在谈论“不运行默认构造函数”,就像一个概念性问题。 您可以使用static属性执行此操作。在那种情况下,不会调用Foo()。但它自然脱离了当前的问题主题。

答案 3 :(得分:1)

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

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

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

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

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

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