5

有了这段代码,我不明白为什么如果在 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 块上。如果我像这样将它从 finally 块中取出:

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

它工作正常。

4

4 回答 4

8

C# 编译器执行的明确分配跟踪不一定执行完整的分析(这在一般情况下是不可能的) - 有一些规则限制了编译器将执行的分析的复杂程度。此处涵盖该finally块的规则记录在http://msdn.microsoft.com/en-us/library/aa691181.aspx

对于以下形式的 try 语句stmt

try 尝试阻止 finally 最终阻止

  • try-blockv开头的确定赋值状态与stmt开头的确定赋值状态相同。v
  • finally-blockv开头的确定赋值状态与stmt开头的确定赋值状态相同。v
  • ...

因此,对于您的特定示例,由于currency在块的开头未明确分配try,因此认为在finally块的开头未明确分配。

于 2011-12-21T23:55:48.483 回答
1

如果在块new CurrencyVO()中导致异常怎么办?catch啊哈!

于 2011-12-22T00:22:43.967 回答
1

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

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

于 2011-12-22T00:25:35.723 回答
0

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

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

CurrencyVO currency = null;

最后:

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

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/a994a0ff-432b-4d23-b7d2-838b0b961de0

于 2011-12-21T23:47:13.130 回答