C# 使用未分配的局部变量。但总是属于任务

C# 使用未分配的局部变量。但总是属于任务,c#,try-catch,unassigned-variable,C#,Try Catch,Unassigned Variable,有了这段代码,我不明白为什么如果在finally块中分配一个变量不理解,那么它将始终被分配。我想我缺少了一个有效的选项,其中货币不会被分配。如果你知道的话,了解原因会很好。非常感谢 谢谢 CurrencyVO currency; try { if (idConnection.HasValue && idConnection != 0) { currencyConnection = client.GetConnection(idConnect

有了这段代码,我不明白为什么如果在finally块中分配一个变量不理解,那么它将始终被分配。我想我缺少了一个有效的选项,其中货币不会被分配。如果你知道的话,了解原因会很好。非常感谢

谢谢

CurrencyVO currency;

try
{
     if (idConnection.HasValue && idConnection != 0)
     {
         currencyConnection = client.GetConnection(idConnection.Value);
         model.Connection = currencyConnection;
     }
     else 
     {
         int providerUserKey = (int)Models.UserModel.GetUser().ProviderUserKey;
         currencyConnection = client.GetConnection(providerUserKey);
     }                        
     currency = model.Currencies.SingleOrDefault(c => c.IdCountry == currencyConnection.idcountry) ?? new CurrencyVO();    
} 
catch
{
      currency = new CurrencyVO();                    
} 
finally
{
      model.PublishedContainer.Currency = currency;
}
错误发生在finally块上。如果我像这样从最后一个块中取出它:

                } catch {
                    currency = new CurrencyVO();
                }
                model.PublishedContainer.Currency = currency;

它工作正常。

您正在catch块内创建一个新的
CurrencyVO
对象:该对象仅在出现错误/异常时才会执行。因此,如果没有遇到异常:
currency
变量将不会被赋值。这就是为什么你不能使用它

编辑:对要编译的代码进行以下更改:

CurrencyVO currency = null;
最后:

if (currency != null)
   model.PublishedContainer.Currency = currency;

C#编译器执行的确定赋值跟踪不一定执行完整的分析(在一般情况下不可能)-有一些规则限制编译器执行的分析的复杂程度。此处涵盖
finally
块的规则记录在:

对于以下形式的try语句stmt:

try
try block
finally
finally block

  • try块开始处的
    v
    的明确分配状态与try块开始处的
    v
    的明确分配状态相同 stmt的开始
  • finally块开头的
    v
    的确定分配状态与finally块开头的
    v
    的确定分配状态相同 stmt的开始

因此,对于您的特定示例,由于
currency
try
块的开头没有明确指定,因此它被认为在
finally
块的开头没有明确指定。

如果
new CurrencyVO()
导致
catch
块中出现异常怎么办?哈哈

您可以在不影响语言规范的情况下进行推理。这里的失败模式是catch块中的语句可以引发异常。很有可能,C#支持在构造函数中抛出异常。但一般来说,任何语句都可能引发异常。这将使变量未初始化。finally块中的赋值将始终执行。在这种情况下使用未初始化的变量


如果相关的话,你需要考虑在这种情况下会发生什么。但显而易见的解决方法是直接将变量初始化为null。

Yoy应将此帖子声明为一个问题,将Try块的最后一行替换为“currency=new CurrencyVO();”不会导致错误,是吗?@SpectralGhost:
try
块内的任何内容都不会更改错误-
try
块之前需要分配货币(即使只是分配
null
)。货币分配在try@Joe:没错,我后来注意到了这一点,但我猜编译器不能保证赋值将被执行,这就是为什么它不允许使用variableReally?似乎它将被分配到try或catch中。必须抓住一个,对吗?在我测试代码时你打败了我:)在上面的示例中,如果CurrencyVO的构造函数抛出异常,执行将在货币仍然未定义的情况下命中finally块。很好。我把接受的答案留给更正式的答案,但这个答案是“聪明的”+1.