C# 初始化混乱!

发布于 2024-07-19 07:37:26 字数 444 浏览 4 评论 0原文

int?  test;
try
{
    test = (int?) Int32.Parse ("7");
} catch {}

if (test == null)
     Console.WriteLine("test is null!");
else
     Console.WriteLine("test = {0}", test);

我有一些代码执行与此非常相似的操作,确实有相同的想法...创建一个变量,尝试初始化它,然后测试以查看初始化是否成功。

Visual Studios 给我一个错误,说“使用未分配的局部变量'test'”,这有点烦人,可以通过将第一行设置为轻松修复:

int?  test = null;

但我很好奇这两行之间的区别是什么,因为编译器似乎真的很关心。 据我所知,这两条线做同样的事情。

int?  test;
try
{
    test = (int?) Int32.Parse ("7");
} catch {}

if (test == null)
     Console.WriteLine("test is null!");
else
     Console.WriteLine("test = {0}", test);

I am have some code that does something VERY similar to this, same idea really... Creating a variable, trying to initialize it, then test to see if the initialization was a success.

Visual Studios is giving me an error saying " Use of unassigned local variable 'test' ", which is kind of annoying, this is easily fixed by setting the first line to:

int?  test = null;

but I am curious what the difference between the two lines are, because the compiler really seems to care. And to the best of my knowledge, the two lines do the same thing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(6

冷︶言冷语的世界 2024-07-26 07:37:26

问题在于 catch 块。 编译器必须假设 Int32.Parse 代码可以抛出异常,从而命中您的 catch 块。 在这种情况下,Int32.Parse 行不会完成,因此永远不会为 test 分配值。 这意味着“if”行正在尝试使用未初始化的值。

您可以通过

  1. 在 catch 块中分配测试值并
  2. 在方法开始时将其初始化为 null 来解决此问题

The problem is the catch block. The compiler must assume the Int32.Parse code can throw and hence hit your catch block. In the case that happens the Int32.Parse line does not complete and hence test is never assigned a value. That means the "if" line is attempting to use an uninitialized value.

You can fix this by

  1. Assigning test a value in the catch block
  2. Initializing it to null at the start of the method
倾城泪 2024-07-26 07:37:26

您混淆了变量声明和变量初始化之间的区别

int?  test;

,只是声明您有一个名为 test 的变量,它是一个可为 null 的 int

,但

int?  test = null;

声明您有一个名为 test 的变量,它是一个可为 null 的 int,并且其值为 null

在VB中没有区别,但在C#中则有区别。 这就是编译器抱怨的原因,因为如果您的 try 块中出现错误,那么您的测试变量将永远不会被初始化。

you're confusing the difference between what is a variable declaration and what is variable initialization

int?  test;

simply states that you have a variable named test that is a nullable int

but

int?  test = null;

states that you have a variable named test that is a nullable int and its value is null

In VB there is no distinction, but in c# there is a difference. That's why the compiler is complaining, because if something fails in your try block then your test variable would never have been initialized.

夜深人未静 2024-07-26 07:37:26

您可以避免 (int?) 强制转换,为“= null”字符串节省 7 个字节:)

test = Int32.Parse ("7");

You can avoid (int?) cast, to save 7 bytes for " = null" string :)

test = Int32.Parse ("7");
不疑不惑不回忆 2024-07-26 07:37:26

对于本地定义的变量(在方法或属性内,而不是直接在类内),总是会发生此错误。 尽管事实仍然是编译器不需要生成此错误才能工作,但它这样做是专门为了帮助您识别在不发生错误的情况下潜在的意外结果。总是分配你的变量。 (如果我错了,有人会纠正我,但至少某些以前版本的 C# 编译器在某些/所有情况下都没有检查未分配的变量。)

等效地(而不是在中分配 test = null声明),您可以通过在 catch 块中设置 test = null 来消除错误,因为这意味着无论代码采用什么路径,都会分配变量 test 。 但是,我认为您所说的解决方案(在声明中分配给 null)是正确的 - 您会在 C# 代码中经常看到它,它包含很多内容(通过 try-catch 语句、if 语句或其他任何方式) ) - 老实说,它只是帮助您了解分配变量的内容和时间,尽管它可能看起来有点烦人。

This is an error that always occurs for locally defined variables (inside a method or property as opposed to directly within the class). Although the fact remains that the compiler need not generate this error in order to work, it does it specifically for the purpose of helping you identify potentialy unexpected results in the case of not always assigning your variables. (Someone correct me if I'm wrong, but at least some previous versions of the C# compiler didn't check for unassigned variables in some/all cases.)

Equivalently (instead of assigning test = null in the declaration), you could eliminate the error by assining test = null in the catch block, since this would mean that whatever path the code takes, the variable test gets assigned. However, I think the resolution that you have stated (assigning to null in the declaration) is the correct one - you'll see it very often in C# code that brances a lot (via try-catch statements, if statements, or whatever else) - and to be honest it's only helping you to realise to what and when you are assigning your variables, even though it may seem like a minor irritance.

渡你暖光 2024-07-26 07:37:26

他们做同样的事情,你是正确的,但是如果你希望 null 被认为是一个不会抛出警告的故意“未设置”变量,则该变量需要显式分配 null 来消除“未分配值”错误。 除此之外,贾里德帕的回答是正确的。

They do the same thing, your are correct, however the variable requires the explicit assignment of null to get rid of the 'unassigned value 'error, if you want null to be considered an intentional 'not set' variable that wont throw warnings. Beyond that, Jaredpar's answer is right on target.

乱了心跳 2024-07-26 07:37:26

我相信这种风格更简洁:

try
{
    int test = Int32.Parse("7");
    Console.WriteLine("Success!");
    // add return statement for successful execution here, if any
}
catch
{
    Console.WriteLine("Disaster!");
    // other return statement here, if any
}

至于编译器错误:任何本地字段都必须在读取之前在代码路径上显式初始化。 未初始化本地字段是一个常见错误,因此它是 C# 中的错误。 C/C++ 仅对此发出警告,如果未初始化并且该值反映了调用堆栈上已有的字节,则它可能会产生*有趣的*结果。

我只能推测这一点,但这可能是显式初始化本地字段的性能方面,与类字段相反:当实例化一个对象时,运行时初始化一次对象内存流的成本较低,但是初始化一个每个方法调用多次本地字段是多余的。

I believe this style is much cleaner:

try
{
    int test = Int32.Parse("7");
    Console.WriteLine("Success!");
    // add return statement for successful execution here, if any
}
catch
{
    Console.WriteLine("Disaster!");
    // other return statement here, if any
}

As for the compiler error: Any local field must be explicitly initialized on a code path before reading it. It is a common error not to initialize local fields, that's why it is an error in C#. C/C++ only warns about this, and it can yield *funny* results if it's not initialized and the value reflects the bytes that already were on the call stack.

I can only speculate on this, but it could be a performance aspect of explicitly initializing local fields, contrary to class fields: When an object is instantiated it is less costly for the run-time to initialize the object memory stream once, however initializing a local field multiple times on every method call is redundant.

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