为什么C#允许将匿名对象赋值给类类型的类字段?

3

例子:

class Foo
{
    public Bar Bar { get; set; }
}

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

...
{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // run-time error
    };
}

为什么C#允许这种赋值?在我看来,这没有意义,但更容易引起错误。

1
因为匿名对象与命名对象不同。您可以将类型更改为 object Bar 并查看... - Afzaal Ahmad Zeeshan
3
听起来好像代码应该会生成一个编译时错误。但实际上并没有。这就是问题所在。 - BoltClock
你需要说 Bar = new Bar { Name = "abc" },或者在 Foo 中说 public Bar Bar { get; set; } = new Bar(); - Wagner DosAnjos
6
你手头的是一个对象初始化器,而不是匿名对象。 - Pieter Witvoet
1
相关:属性初始化不会调用List<T>的set方法(虽然描述的是集合初始化器,但原理相同) - BoltClock
显示剩余2条评论
2个回答

7
这是因为如果对象已经实例化,它不会引起运行时错误。
class Foo
{
    public Bar Bar { get; set; } = new Bar();
}

{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // no error
    };
}

你的意思是“实例化”。显然,新表达式是试图初始化Bar实例的表达式。它只需要一个实例就可以开始,无论它是否已经被作者的定义初始化。 - BoltClock

4

实际上这并不是匿名对象,而是使用对象初始化器语法。

{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // run-time error
    };
}

上述代码片段实际上与以下内容相同:
{
    var foo = new Foo();
    foo.Bar = new Bar { Name = "abc" }; // Fine, obviouslly
    foo.Bar = { Name = "abc" }; // compile error
}

使用对象初始化程序语法后,对象名称变得多余,因为它已经知道了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接