C#未初始化的变量有危险吗? [英] Are C# uninitialized variables dangerous?

查看:105
本文介绍了C#未初始化的变量有危险吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉C#规范,第5.3节

I'm familiar with the C# spec, section 5.3 which says that a variable has to be assigned before use.

在C和非托管C ++中,这是有道理的,因为不会清除堆栈,并且将内存位置用于指针可能在任何地方(导致难以跟踪错误)。

In C and unmanaged C++ this makes sense as the stack isn't cleared and the memory location used for a pointer could be anywhere (leading to hard to track down bug).

但是我给人的印象是运行时并没有真正的未分配值。特别是,未初始化的引用类型将始终为null值,永远不会是该方法先前的调用或随机值留下的值。

But I am under the impression that there are not truly "unassigned" values allowed by the runtime. In particular that a reference type that is not initialized will always have a null value, never the value left over from a previous invocation of the method or random value.

这是是正确的,还是我错误地认为这些年来检查空值就足够了?您可以在C#中使用真正的非初始化变量吗,还是CLR会处理这个问题,并且总是有一些值集。

Is this correct, or have I been mistakenly assuming that a check for null is sufficient all these years? Can you have trully unintialized variables in C#, or does the CLR take care of this and there's always SOME value set.

推荐答案


我的印象是,运行时没有真正的未分配值。特别是,未初始化的引用类型将始终具有null值,永远不会具有先前调用方法或随机值后遗留下的值。 这样对吗?

我注意到还没有人回答您的问题。

I note that no one has actually answered your question yet.

您实际提出的问题的答案是 sorta。

The answer to the question you actually asked is "sorta".

正如其他人指出的那样,某些变量(数组元素,字段等)被归类为自动初始分配为其默认值。 (对于引用类型,它为null;对于数字类型,它为零;对于布尔类型,它为false;对于用户定义的结构,其自然递归)。

As others have noted, some variables (array elements, fields, and so on) are classified as being automatically "initially assigned" to their default value. (Which is null for reference types, zero for numeric types, false for bools, and the natural recursion for user-defined structs).

某些变量未归类为初始分配;尤其是局部变量最初并未分配。在使用它们的的所有点上,编译器都必须将它们分类为绝对分配。

Some variables are not classified as initially assigned; local variables in particular are not initially assigned. They must be classified by the compiler as "definitely assigned" at all points where their values are used.

您的问题实际上是是归类为不确定分配的局部变量,实际上是初始分配的字段,与字段的使用方式相同?这个问题的答案是,实际上,运行时最初会分配所有本地人。

Your question then is actually "is a local variable that is classified as not definitely assigned actually initially assigned the same way that a field would be?" And the answer to that question is yes, in practice, the runtime initially assigns all locals.

这有几个不错的属性。首先,您可以在调试器中观察它们在第一次分配之前处于默认状态。第二,垃圾回收器不会被欺骗去引用错误的指针,仅仅是因为堆栈上有剩余的垃圾现在被视为托管引用。等等。

This has several nice properties. First, you can observe them in the debugger to be in their default state before their first assignment. Second, there is no chance that the garbage collector will be tricked into dereferencing a bad pointer just because there was garbage left on the stack that is now being treated as a managed reference. And so on.

允许运行时间离开本地人的初始状态,因为只要可以安全地进行垃圾处理就可以。但是,作为实现细节,它永远不会选择这样做。它积极地将局部变量的内存清零。

The runtime is permitted to leave the initial state of locals as whatever garbage happened to be there if it can do so safely. But as an implementation detail, it does not ever choose to do so. It zeros out the memory for a local variable aggressively.

之所以必须使用本地语言的规则是 not ,以防止您观察到垃圾的未初始化状态本地的。这已经是不可观察的了,因为CLR会积极地将局部变量清除为其默认值,就像对字段和数组元素一样。 这在C#中是非法的,是因为使用未分配的本地很可能会成为错误。我们只是将其设为非法,然后编译器阻止您出现此类错误。

The reason then for the rule that locals must be definitely assigned before they are used is not to prevent you from observing the garbage uninitialized state of the local. That is already unobservable because the CLR aggressively clears locals to their default values, the same as it does for fields and array elements. The reason this is illegal in C# is because using an unassigned local has high likelihood of being a bug. We simply make it illegal, and then the compiler prevents you from ever having such a bug.

这篇关于C#未初始化的变量有危险吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆