Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.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#_Constructor_Initialization - Fatal编程技术网

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

C# 在构造函数运行之前,我可以使用对象初始化语法为属性赋值吗?,c#,constructor,initialization,C#,Constructor,Initialization,我正在使用System.XML.Serialization将对象序列化为XML,这需要使用无参数构造函数 因此,我尝试使用对象初始化语法将值分配给某些属性,然后在将对象序列化为XML之前,使用构造函数逻辑按需要格式化这些值 我的问题是,构造函数在为属性赋值之前运行。下面是一个简化的例子: class Program { static void Main(string[] args) { Foo myFoo = new Foo() { HelloWorld = "B

我正在使用
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);
    }
}
这将产生以下输出:

如您所见,构造函数逻辑运行,然后属性被赋值。我需要这个来解决另一个问题


这可能吗?

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

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

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

Foo foo = new Foo { HelloWorld  = "Beer" };
Foo foo = new Foo();
foo.HelloWorld  = "Beer";
编译器只是将其重写为非常接近以下情况的内容:

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

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

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

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


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

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

var myFoo = new Foo();
myFoo.HelloWorld = "Beer";
myFoo.HelloWorldAgain = "MoreBeer";
恐怕就这样了。在构造函数运行之前,根本不可能初始化属性。构造函数是在为对象分配内存并为字段分配默认值之后“发生”的第一件事

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


看看您的问题,您试图做的事情(在序列化之前修改属性)似乎不属于构造函数。

XML序列化确实要求有一个无参数的公共构造函数,但您可以按照您对API使用者的建议使用其他构造函数重载。@Reed,学究,正如你所写的。@KirkWoll非常正确-我编辑了语言-它只是在概念上与心智模型相似,但是的,它并不完全相同;)你打算做什么样的预序列化格式?我传入一个ID,然后对数据库运行查询,以提取各种信息,并将这些信息分配给自动属性,我认为在构造函数中这样做会更整洁