Sna*_*ake 17 .net c# variables initialization
我有以下代码:
class Foo
{
public Foo()
{
Bar bar;
if (null == bar)
{
}
}
}
class Bar { }
Run Code Online (Sandbox Code Playgroud)
代码专家已经看到这会给出错误.在if语句之前可能没有初始化Bar.
所以现在我想知道:酒吧的价值是什么,不应该是空的吗?它们不是设置为空吗?(空指针?)
Jon*_*eet 36
不,局部变量没有默认值1.在阅读之前必须明确指定它们.这减少了你使用你认为你给出了合理值的变量的可能性,实际上它有一些默认值.这不能用于实例或静态变量,因为您不知道将调用方法的顺序.
有关明确赋值的更多详细信息,请参见C#3.0规范的第5.3节.
请注意,这与作为引用类型变量无关.这将无法以相同的方式编译:
int i;
if (i == 0) // Nope, i isn't definitely assigned
{
}
Run Code Online (Sandbox Code Playgroud)
1就语言而言,无论如何......显然存储器中的存储位置中有一些东西,但它是无关紧要的和特定于实现的.有一种方法可以找出该值是什么,通过创建一个带out参数的方法,然后使用IL来查看方法中该参数的值,而不给它另一个值.CLR根本不介意.然后,您可以调用该方法传入一个非明确赋值的变量,并且看到您可以检测到该值 - 这可能基本上是"全零"值.
我怀疑CLI规范确实强制执行具有默认值的局部变量 - 但我必须检查.除非你像上面那样做了邪恶的事情,否则在C#中对你来说无关紧要.
字段(类/结构上的变量)初始化为null/ zero/etc.局部变量......好 - 因为(通过"明确的分配")你不能在没有分配的情况下访问它们,没有明智的回答方式; 简单地说,它没有被定义,因为它是不可能的.我相信它们碰巧是null/ zero/etc(可以out通过动态IL生成来破解一些代码来证明),但这是一个实现细节.
有关信息,这里有一些狡猾的代码,显示正式未初始化的变量的值:
using System;
using System.Reflection.Emit;
static class Program
{
delegate void Evil<T>(out T value);
static void Main()
{
MakeTheStackFilthy();
Test();
}
static void Test()
{
int i;
DynamicMethod mthd = new DynamicMethod("Evil", null, new Type[] { typeof(int).MakeByRefType()});
mthd.GetILGenerator().Emit(OpCodes.Ret); // just return; no assignments
Evil<int> evil = (Evil<int>)mthd.CreateDelegate(typeof(Evil<int>));
evil(out i);
Console.WriteLine(i);
}
static void MakeTheStackFilthy()
{
DateTime foo = new DateTime();
Bar(ref foo);
Console.WriteLine(foo);
}
static void Bar(ref DateTime foo)
{
foo = foo.AddDays(1);
}
}
Run Code Online (Sandbox Code Playgroud)
IL 只是做了"退缩" - 它从不分配任何东西.