【问题标题】:Local variable unassigned issue using Try, catch, finally使用 Try、catch、finally 的局部变量未分配问题
【发布时间】:2015-04-29 05:52:34
【问题描述】:

我想知道是否可以帮忙。有人可以向我解释为什么我的字符串 sqrtfinally 块中未分配吗?为什么我必须申报?为什么不能在 try 或 catch 语句中声明?这将使编码变得不那么乏味,更有条理。

    private void btnDisplay_Click(object sender, EventArgs e)
    {
        int number;

        string sqrt;

        try
        {

            number = Convert.ToInt32(tbInput.Text);
            //Why cant i just have it as "number=COnvert.ToDouble(tbInput.Text)?//
            Convert.ToDouble(number);
            if (number < 0)
            {
                throw new NegativeNumberException();
            }
            sqrt = Math.Sqrt(number).ToString();


        }
        catch (FormatException error)
        {
            lbOutput.Items.Add(error.Message);
            lbOutput.Items.Add("The input should be a number.");
            sqrt = "not able to be calculated";


        }
        catch (NegativeNumberException neg)
        {
            lbOutput.Items.Add(neg.Message);
            sqrt = "not able to be calculated";


        }
        finally
        {
            //Here is where i am having the issue "Unassigned local variable"//
            lbOutput.Items.Add("Square Root " + sqrt);
        }

    }

       class NegativeNumberException : Exception
       {
          public NegativeNumberException()
            : base("Number can’t be negative")
          {

          }



      }
    }
}

我试图在 finally 块中实现的是“平方根”和“sqrt”显示在列表框中,无论 sqrt 的值是什么。如果我将 sqrt 输出到任何其他块中的列表框,它就可以工作(因为它已被声明)。有谁知道我该怎么做?我敢打赌,这可能也很简单。我不是要咆哮或任何事情,只是我在过去的 12 个小时里一直在起床,所以我开始感到挫败。感谢大家的帮助,我真的很感谢。

【问题讨论】:

  • 声明变量 number 比你能做的两倍 number=Convert.ToDouble(number);
  • 好吧,这样看:finally 保证始终运行,无论如何(不包括电源故障等)。那么如果在设置sqrt 之前catch 块中的某些内容出错了怎么办?或者如果抛出了你没有捕捉到的异常怎么办?然后sqrt 没有设置,换句话说“未分配”。因此,解决这个问题的最简单方法是立即将其初始化为 something。喜欢:string sqrt = string.Empty; 甚至是string sqrt = null;
  • @Corak,完美,我在任何块之前初始化了字符串,现在它继续存在。再次感谢您的帮助。 ^_^
  • @Spr89 - 有一个细微但重要的区别。分配给sqrt 的值将始终被“继承”,但代码中的某些路径可能会导致finally 块,而无需为sqrt 分配任何内容。因此,在开头分配 somethingnullstring.Empty 甚至 "Hello World")可以保证,在finally 块运行。

标签: c# string try-catch-finally listboxitems


【解决方案1】:

如果您的代码中有以下任何一行:

number = Convert.ToInt32(tbInput.Text);
//Why cant i just have it as "number=COnvert.ToDouble(tbInput.Text)?//
Convert.ToDouble(number);
if (number < 0)
{
    throw new NegativeNumberException();
}

抛出不属于NegativeNumberExceptionFormatException 类型的异常,然后由于此声明:

string sqrt;

您的 sqrt 变量仍未分配。

你可以通过如下声明来解决这个问题:

string sqrt = null; // or ""

关于您的评论:

为什么我不能将其设为“number=CONvert.ToDouble(tbInput.Text)?

试试这个:

var number = Double.Parse(tbInput.Text);

【讨论】:

  • ahhhh,不知道,所以基本上没有办法让字符串值结转?即使它在任何其他块中声明?
  • 可能会抛出与您正在处理的两个不同的异常,并导致 sqrt 保持未初始化状态。
  • @Spr89 - 它“结转”,但您的代码不能保证在finally 运行之前肯定会有分配。
【解决方案2】:

您不能在try 块中声明它,因为局部变量是由scope 绑定的。简而言之,在块中声明的局部变量,即{},仅在该块中可见。对于插件,最好将sqrt初始化为""string.Empty,同时声明它。

【讨论】:

    【解决方案3】:

    改变:

    int number;
    string sqrt;
    

    更新:

    double number = 0.0;
    string sqrt = string.Empty;
    

    【讨论】:

    • 为什么这个答案会解决 OP 的问题?我的意思是,发布一堵代码作为答案,而没有解释为什么这是一个答案,这是一个无用的答案。
    • 我已经改了double number = 0.0; string sqrt = string.Empty;试试看。
    • 不是我的问题,我不需要尝试代码就知道它会做什么。同样,我的观点是包括对更改的解释以及为什么它会使代码工作将是一个很好的答案。仅代码的答案不会教任何人任何东西。您所做的更改和为什么的解释应该在您的回答中。
    【解决方案4】:

    尝试在 sqrt 上分配一个值。 string sqrt = "";//关于声明 sqrt 可能不包含任何调用问题的值。

    【讨论】:

      【解决方案5】:

      @Corak,在任何块解决问题之前初始化字符串。

      我变了

           string sqrt;
      

           string sqrt=string.Empty;
      

      【讨论】:

        【解决方案6】:

        sqrt 仅在它声明的范围内可用。范围通常由花括号分隔,例如方法体、for 语句,或者在本例中是 try、catch 和 finally 子句。尝试在 if 子句中声明变量时,您会注意到同样的问题,然后尝试在 else 对应项中使用该变量。如果你有很多这些,并且只在 try 或 catch 子句中声明它,一种选择是创建一个全局变量映射,然后将“sqrt”键分配给每个范围内你想要的对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-01
          • 2014-12-13
          • 1970-01-01
          相关资源
          最近更新 更多