我使用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);
}
}
这导致以下输出:
如您所见,构造函数逻辑运行,然后为属性分配值。我需要这个以相反的方式工作。
这可能吗?
答案 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" };
查看您的问题,看起来您正在尝试执行的操作(在序列化之前修改属性)不属于构造函数。