这是 C# 4.0 编译器中的错误吗?
这段代码编译成功,但我认为它应该编译失败。此外,当您运行它时,您会收到一个 NullReferenceException 异常。缺少的代码是 Bar
属性初始化中的“new Bar”。
class Bar
{
public string Name { get; set; }
}
class Foo
{
public Bar Bar { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo
{
Bar = { Name = "Hello" }
};
}
}
这是一个已知的错误吗?
This code compiles successfully, but I think it should fail to compile. Also, when you run it you get a NullReferenceException
. The missing code is the "new Bar" in the initialization of the Bar
property.
class Bar
{
public string Name { get; set; }
}
class Foo
{
public Bar Bar { get; set; }
}
class Program
{
static void Main(string[] args)
{
var foo = new Foo
{
Bar = { Name = "Hello" }
};
}
}
Is this a known bug?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
为什么你认为它应该无法编译?它是嵌套对象初始值设定项语法,客户端代码负责为初始化提供有效值。
来自文档:
C# 规范 7.5.10.2“对象初始值设定项”
Why do you think it should fail to compile? It is nested object initializer syntax, and it is the responsibility of the client code to provide a valid value for initialization.
From the documentation:
C# spec 7.5.10.2 "Object initializers"
不,这不是一个错误。
如果您希望它运行,您可以在
Bar
之前放置一个new
(就像您在初始化程序之前对 Foo 所做的那样),或者在 Foo 的构造函数中创建 Bar 对象。对象初始值设定项本质上只是语法糖。
这:
与此完全相同:
No this is not a bug.
If you want it to run you either put a
new
beforeBar
(just like you did for Foo before the initializer) or you create the Bar object in Foo's constructor.The object initializer is essentially just syntactic sugar.
This:
Is exactly the same as this:
new
在对象初始值设定项中是不必要的:最后一个是最重要的。它代表
property = value
语法的右侧。这意味着右侧可以是普通的 C# 表达式(带有new
运算符)或另一个初始化器。在这种情况下,您所需要的只是左大括号和右大括号。The
new
is unecessary in an object initializer:It's that last one that is most important. It represents the right-hand-side of your
property = value
syntax. This means that the right-hand-side can be a normal c# expression (with anew
operator) or another initalizer. In which case, all you need are the opening and closing braces.如果将代码更改为以下等效代码,您还将收到 NullReferenceException 的运行时错误,而不是编译时错误/警告。
效果是一样的,Bar 永远不会被正确初始化。现在,从编译器编写者的角度来看,在所有情况下都很难确定 Bar 在使用之前是否已正确初始化。
If you change your code to the following equivalent, you will also get a runtime error of a NullReferenceException instead of a compile time error/warning.
The effect is the same, Bar is never properly initialized. Now, from a compiler writers perspective it is extremely difficult to determine in all cases as to whether Bar was properly initialized prior to use.
意思是:
Foo.Bar.Name="Hello"
不是:
{Foo.Bar=new Bar(); Foo.Bar.Name="Hello";}
这将编译并且不会抛出任何异常,因此这不是一个错误,您只是初始化一个不存在的对象:
means:
Foo.Bar.Name="Hello"
not:
{Foo.Bar=new Bar(); Foo.Bar.Name="Hello";}
This will compile and will not throw any exception, so it's not a bug, you're just initializing an unexisting object:
Bar
是Foo
的一个属性,因此它允许您在编译时访问它并分配一个 name 属性,但在运行时它会检查的有效实例code>Bar
不存在,因此会抛出空引用异常,任何 C# 版本都会出现这种情况。Bar
is a property ofFoo
, so it is allowing you to access it and assigning a name property at compile time, but at run time it checks for the valid instance ofBar
which is not present so throwing null reference exception, it will be the case with any C# version.我创建了一个工作示例。
很简单,只需添加一个“new Bar()”即可正常工作
I create a working sample.
Its easy, only add a "new Bar()" an it work fine