null 和未初始化之间的区别?
当我用 C# 编写以下代码时:
SqlCeCommand command;
try
{
// The command used to affect the data
command = new SqlCeCommand
{
// init code removed for brevity
};
// Do stuff
// Do more stuff
}
finally
{
if (command != null)
command.Dispose();
}
Resharper 抱怨我检查命令 != null。它表示该命令可能不会被分配(因为它可能在构建过程中失败,但仍然会命中 try 块)。
因此,我将命令的声明更改为 SqlCeCommand command = null;
,每个人都很高兴。
但我想知道有什么区别?
为什么它不直接默认为 null 呢? 含义:C# 不仅仅将局部变量默认为 null 有何好处?
When I write the following code in C#:
SqlCeCommand command;
try
{
// The command used to affect the data
command = new SqlCeCommand
{
// init code removed for brevity
};
// Do stuff
// Do more stuff
}
finally
{
if (command != null)
command.Dispose();
}
Resharper complains on my check of command != null. It says that command may not be assigned (because it could fail some how in the constructing and still hit the try block).
So I change the declaration of command to be SqlCeCommand command = null;
and everyone is happy.
But I am left wondering what the difference is?
And why doesn't it just default to null? Meaning: How does C# benefit from not just defaulting local variables to null?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
局部变量没有默认值。语言的一部分。
Local variables have no default value. Part of the language.
好吧,如果你希望它为空,那么你需要告诉它。这是为了捕捉 bug。编译器和 ReSharper 等实用程序会搜索所有执行路径,并确保变量在使用之前已初始化。这是为了发现常见的编码错误。因此,不可能有额外的“甚至不是空”值,这只是编译器(或其他)为帮助您而完成的分析。
类成员被初始化为默认值(例如,引用类型为 null),因此您可以获得预期的行为。
Well if you want it to be null then you need to tell it to. This is to catch bugs. The compiler and utilities like ReSharper searches all execution paths and makes sure that variables are initialized before they are being used. This is to catch common coding mistakes. So there is no additional "not even null" value possible, it is only an analysis done by the compiler (or whatever) to help you out.
Class members are initialized to default values (e.g. null for reference types), so there you get the behavior you expect.
这与 C# 帮助确保代码正确性的目标有关。在类声明中(与局部变量相反),成员具有隐式值,因此您不必在声明或类构造函数中显式设置它们。然而,在函数/方法的上下文中,C# 会跟踪变量是否已显式设置,以便它可以向您发出警告,就像您所看到的那样......这是一个设计决策就语言而言。
This has to do with C#'s goal to help ensure code correctness. In a class declaration (as opposed to with local variables), members have implicit values so that you don't have to explicitly set them in the declaration or the class constructor. In the context of a function/method, however, C# tracks whether a variable has been explicitly set, so that it can warn you about things just like what you're seeing... it's a design decision on the part of the language.
您可以使用
using
构造来编写等效但更紧凑的代码,该构造为您调用Dispose
:您无需担心处置或检查是否为空。
You can write equivalent but more compact code with
using
construct that callsDispose
for you:You won't need to worry neither about disposing nor about checking for nullity.
类字段成员获得默认值(每个值类型取决于其类型,引用类型为 null),但局部变量则不然。
编辑:这是为了避免导致程序意外关闭(由于空指针)的 C++ 运行时错误而设计的。
PS:当我谈论 C# 规范时,你可能不会对我投反对票(我没有制定 C# 规范,不过我对这种回避表示欢迎)。
Class field members get defaulted (value types each depending on its type, ref types to null) but local variables do not.
EDIT: This was designed to avoid C++ runtime errors which was causing the program to close unexpectedly (because of null pointers).
P.S: You may not downvote me when I talk about C# specs (I didn't make C# specs, I cheer this avoidance though).
您可以测试 null,因为 null 是一个值。
未初始化意味着没有值,因此您无法对其进行测试。
You can test for null as null is a value.
Not initialized means no value so you can not test for it.