C# 字典初始值设定项编译不一致
以下代码可以编译,但会失败并出现 NullReferenceException
:
class Test
{
public Dictionary<string, string> Dictionary { get; set; }
}
static void Main(string[] args)
{
var x = new Test
{
Dictionary = // fails
{
{ "key", "value" }, { "key2", "value2" }
}
};
}
如果将标记为“失败”的行替换为以下内容,则它可以正常工作(如预期):
Dictionary = new Dictionary<string, string>
失败的语法是否有任何目的 - 可以吗在其他情况下可以成功使用吗?或者这是编译器的疏忽?
The following code compiles, but fails with a NullReferenceException
:
class Test
{
public Dictionary<string, string> Dictionary { get; set; }
}
static void Main(string[] args)
{
var x = new Test
{
Dictionary = // fails
{
{ "key", "value" }, { "key2", "value2" }
}
};
}
If you replace the line marked 'fails' with the following, it works (as expected):
Dictionary = new Dictionary<string, string>
Is there any purpose to the failing syntax--can it be used successfully in some other case? Or is this an oversight in the compiler?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,这不是一个错误...这是您对初始化语法的理解中的一个缺陷:)
这个想法
适用于调用者对集合属性有读取访问权限,但没有访问权限的情况写访问权限。换句话说,像这样的情况:
基本上最终会调用 Add,但不会先创建新集合。所以这段代码:
相当于:
一个很好的例子说明它的用处是 UI 的
Controls
集合。您可以这样做:但您实际上无法设置
Controls
属性,因为它是只读的。No, it's not a mistake... it's a flaw in your understanding of initialization syntax :)
The idea of the
is for cases where the caller has read access to a collection property, but not write access. In other words, situations like this:
Basically it ends up being calls to Add, but without creating a new collection first. So this code:
is equivalent to:
A good example of where this is useful is with the
Controls
collection for a UI. You can do this:but you couldn't actually set the
Controls
property, because it's read-only.您仍然可以在构造函数中使用您想要的语法:
You can still use the syntax you want in a constructor:
它因空引用异常而失败,因为您声明了一个未初始化的变量(字典),因此它为空。
当您尝试使用初始化语法向其中添加条目时,您正在尝试将数据写入空对象。
当您用“= new Dictionary...”替换该行时,您正在创建一个新对象供 Dictionary 引用,因此您可以成功向其中添加条目。
(在 Jon Skeet 的示例中,Controls 集合必须已经由 Form 创建,因此它可以正常工作)
It fails with a null reference exception because you have declared a variable (Dictionary) that is unintialised, hence it is null.
When you attempt to add the entries into it using the initialiser syntax, you are trying to write data into a null object.
When you replace the line with a "= new Dictionary...", you are creating a new object for Dictionary to reference, and hence you are then able to add entries into it successfully.
(In Jon Skeet's example, the Controls collection must already have been created by the Form, hence it works ok)