代码之家  ›  专栏  ›  技术社区  ›  Meiscooldude

初始化混乱!

  •  0
  • Meiscooldude  · 技术社区  · 15 年前
    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;
    

    但我很好奇这两行之间的区别是什么,因为编译器似乎真的很在意。据我所知,这两条线的作用是一样的。

    6 回复  |  直到 15 年前
        1
  •  5
  •   JaredPar    15 年前

    问题是抓块。编译器必须假定int32.parse代码可以抛出,从而命中catch块。在这种情况下,int32.parse行没有完成,因此测试从来没有赋值。这意味着“if”行试图使用未初始化的值。

    你可以通过

    1. 在catch块中为测试赋值
    2. 在方法开始时将其初始化为空
        2
  •  1
  •   Joseph    15 年前

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

    int?  test;
    

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

    但是

    int?  test = null;
    

    声明您有一个名为test的变量,该变量是一个可为空的int,其值为空。

    在VB中没有区别,但在C中有区别。这就是编译器抱怨的原因,因为如果try块中有什么失败了,那么测试变量就永远不会被初始化。

        3
  •  1
  •   Ivan Sokalskiy    15 年前

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

    test = Int32.Parse ("7");
    
        4
  •  1
  •   Noldorin    15 年前

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

    等价(而不是分配 test = null 在声明中),您可以通过 测试=空 在catch块中,因为这意味着无论代码采用什么路径,变量 test 分配。但是,我认为您所声明的解决方案(在声明中指定为空)是正确的解决方案-您经常会在C代码中看到它(通过尝试捕捉语句、if语句或其他任何方式),而且老实说,它只是帮助您了解分配变量的内容和时间,即使它可能像是轻微的刺激。

        5
  •  0
  •   cyberconte    15 年前

    它们做同样的事情,您的是正确的,但是变量需要显式分配空值以消除“未分配值”错误,如果您希望将空值视为不会引发警告的有意“未设置”变量。除此之外,贾雷德帕的回答是正确的。

        6
  •  0
  •   Cecil Has a Name    15 年前

    我相信这种风格要干净得多:

    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++只警告这一点,如果它没有初始化,它可以产生*Frase*结果,并且该值反映已经在调用堆栈上的字节。

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