null 和未初始化之间的区别?

发布于 2024-10-18 14:21:37 字数 595 浏览 1 评论 0原文

当我用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

追风人 2024-10-25 14:21:37

局部变量没有默认值。语言的一部分。

Local variables have no default value. Part of the language.

花想c 2024-10-25 14:21:37

好吧,如果你希望它为空,那么你需要告诉它。这是为了捕捉 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.

极度宠爱 2024-10-25 14:21:37

这与 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.

静谧幽蓝 2024-10-25 14:21:37

您可以使用 using 构造来编写等效但更紧凑的代码,该构造为您调用 Dispose

using (var command = new SqlCeCommand
       { 
           // init code removed for brevity
       })
{

    // Do stuff 
    // Do more stuff
}

您无需担心处置或检查是否为空。

You can write equivalent but more compact code with using construct that calls Dispose for you:

using (var command = new SqlCeCommand
       { 
           // init code removed for brevity
       })
{

    // Do stuff 
    // Do more stuff
}

You won't need to worry neither about disposing nor about checking for nullity.

轻拂→两袖风尘 2024-10-25 14:21:37

类字段成员获得默认值(每个值类型取决于其类型,引用类型为 null),但局部变量则不然。

// Example 1:
SomeClass someObject;
if(x == y)
{
    someObject = new SomeClass();
}
someObject.someMethod();   //Error since it may not execute the if statements

// Example 2
SomeClass someObject;
someObject = new SomeClass();
someObject.someMethod();   //No Error

编辑:这是为了避免导致程序意外关闭(由于空指针)的 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.

// Example 1:
SomeClass someObject;
if(x == y)
{
    someObject = new SomeClass();
}
someObject.someMethod();   //Error since it may not execute the if statements

// Example 2
SomeClass someObject;
someObject = new SomeClass();
someObject.someMethod();   //No Error

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).

水中月 2024-10-25 14:21:37

您可以测试 null,因为 null 是一个值。
未初始化意味着没有值,因此您无法对其进行测试。

You can test for null as null is a value.
Not initialized means no value so you can not test for it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文