初始化语法

lep*_*pie 29 .net c# object-initializers

我喜欢C#3初始化器语法并且使用它很多,但今天在查看Reflector时,出现了以下内容:

var binding = new WSHttpBinding
{
  ReaderQuotas = { MaxArrayLength = 100000 },
  MaxReceivedMessageSize = 10485760
};
Run Code Online (Sandbox Code Playgroud)

起初我认为这是一个错误,但它确实编译!我猜我一直都在学习新东西.:)

据我所知,它设置了MaxArrayLength属性的ReaderQuotas属性WSHttpBinding.

此语法是创建新ReaderQuotas对象然后设置属性,还是假设要初始化属性?这是用于初始化"子"属性的一般方式吗?

我发现语法有点令人困惑......

Mar*_*ell 22

不,除非您使用= new SomeType {...}以下内容,否则不会创建新对象:

var binding = new WSHttpBinding
{
    ReaderQuotas = new XmlDictionaryReaderQuotas { MaxArrayLength = 100000 },
    MaxReceivedMessageSize = 10485760
};
Run Code Online (Sandbox Code Playgroud)

您的示例显示了用于设置现有子对象属性的初始化语法.在集合上调用"添加"方法也有类似的语法.

您的代码与以下内容大致相当:

var binding = new WSHttpBinding();
binding.ReaderQuotas.MaxArrayLength = 100000;
binding.MaxReceivedMessageSize = 10485760;
Run Code Online (Sandbox Code Playgroud)

  • 不值得一个额外的答案 - 但这将在深度C#的第8章中讨论.本章的第一版可从http://manning.com/skeet/免费获得. (2认同)
  • 詹姆斯,区别是微妙的.虽然代码在语义上等同于我们,但实际上我们生成了"temp = new Binding(); blah blah blah; var binding = temp;" 为什么?因为*变量"绑定"不能在其自己的初始化程序中使用!*这将是一个鸡与蛋的问题.如果我们完全按照Marc的建议生成代码,那么在初始化程序代码运行*之前,"绑定"将被初始化*,并且有人可能会在其部分初始化状态中观察到"绑定". (2认同)

Eri*_*ert 14

我同意,这有点令人困惑.

您应该阅读规范的第7.6.10.2节; 这一切都在那里解释.例如:

成员初始值设定项指定等号后面的表达式,其处理方式与对字段或属性的赋值相同.

在等号后面指定对象初始值设定项的成员初始值设定项是嵌套对象初始值设定项,即嵌入对象的初始化.而不是为字段或属性分配新值,嵌套对象初始值设定项中的赋值被视为对字段或属性成员的赋值.嵌套对象初始值设定项不能应用于具有值类型的属性,也不能应用于具有值类型的只读字段.

在等号后面指定集合初始值设定项的成员初始值设定项是嵌入式集合的初始化.而不是将新集合分配给字段或属性,初始化程序中给出的元素将添加到字段或属性引用的集合中.