无法识别的C#语法

时间:2016-11-17 20:26:18

标签: c# .net

让我们说:

class Foo
{
    public int IntPropertyInFoo { get; set; }

    public Bar BarPropertyInA { get; set; }
}

class Bar
{
    public string StringPropertyInBar { get; set; }
}

然后我们想用对象初始值设定项实例化Foo

public static void Main(string[] args)
{
    var foo = new Foo
    {
        IntPropertyInFoo = 123,
        BarPropertyInA = // Ommiting new and type name - why does it compile?
        {
            StringPropertyInBar = "something"
        }
    };
}

初始化BarPropertyInA的语法让我感到困惑,因为代码在没有警告的情况下编译,并且在运行时抛出NullReferenceException。我没有认识到这种语法,但是当它与字段一起使用时,它似乎具有相同的效果,而不是属性。

反汇编已编译的代码会产生以下结果:

.method public hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       34 (0x22)
  .maxstack  3
  .locals init ([0] class Test.Foo foo)
  IL_0000:  nop
  IL_0001:  newobj     instance void Test.Foo::.ctor()
  IL_0006:  dup
  IL_0007:  ldc.i4.s   123
  IL_0009:  callvirt   instance void Test.Foo::set_IntPropertyInFoo(int32)
  IL_000e:  nop
  IL_000f:  dup
  IL_0010:  callvirt   instance class Test.Bar Test.Foo::get_BarPropertyInA()
  IL_0015:  ldstr      "something"
  IL_001a:  callvirt   instance void Test.Bar::set_StringPropertyInBar(string)
  IL_001f:  nop
  IL_0020:  stloc.0
  IL_0021:  ret
} // end of method Program::Main

看起来像:

public static void Main(string[] args)
{
    var foo = new Foo
    {
        IntPropertyInFoo = 123
    };

    foo.BarPropertyInA.StringPropertyInBar = "something";
}

如果属性/字段在构造函数中初始化,那么这应该是初始化属性&field的成员的一些语法糖吗?

1 个答案:

答案 0 :(得分:2)

是的,它是一种初始化属性的简写,这些属性从空开始而不是空。 .net集合属性就是一个很好的例子。

var cmd = new System.Data.SqlClient.SqlCommand()
{
    Parameters = 
    {
        new System.Data.SqlClient.SqlParameter() { ParameterName = "@p1", Value = "SomValue"}
    },
    CommandText = "select 1 from Table1 where Value = @p1"
};

它还允许您初始化只读属性的值。

//compiles and works
var message = new MailMessage { To = { "test@stackoverflow.com" } };

message = new MailMessage
{
    // won't compile: To is read-only
    To = new MailAddressCollection { "test@stackoverflow.com" },
};

从这篇文章中逐字借词: http://www.codeducky.org/even-concise-c-object-initializers/

  

New-less初始化程序语法允许您使代码更简洁,并使用初始化语法来配置只读属性。实际上,由于大多数基类库和流行的.NET包类遵循集合属性的空的空模式,因此几乎总能利用新的语法。最后,使用new-less初始化还意味着您可以通过保留对象初始化的任何默认值而受益。