c#在Try.atch之后使用未分配的局部变量

本文关键字:分配 局部变量 Try atch 之后 | 更新日期: 2023-09-27 18:10:48

我正在使用下面的代码来获取MS Word的运行实例。

我现在有一个编译问题'使用未分配的局部变量"oWord"'

这是我的代码:

Microsoft.Office.Interop.Word._Application oWord ; 
try
{
// Is Word running?
oWord = Marshal.GetActiveObject("Word.Application") as Microsoft.Office.Interop.Word.Application; // ApplicationClass;
}
catch (COMException ce)
{
if (ce.ErrorCode == unchecked((int)0x800401E3))
    // No, Word not in ROT, start a new instance
    oWord = new Microsoft.Office.Interop.Word.Application();
}
// Use instance referened by _WordApp 
oWord.ScreenUpdating = false; // < PROBLEM HERE
object objDefaultBehaviorWord8 = WdDefaultTableBehavior.wdWord8TableBehavior;
object objAutoFitFixed = WdAutoFitBehavior.wdAutoFitFixed;
//MAKING THE APPLICATION VISIBLE
oWord.Visible = Properties.Settings.Default.DebugMode;
oWord.DisplayAlerts = WdAlertLevel.wdAlertsNone;

但在我看来,oWord被分配了,我猜编译器正在查看我的Try。。捕获块并说我已取消分配oWord

那么,正确的分配方式是什么呢?

c#在Try.atch之后使用未分配的局部变量

如果Marshal.GetActiveObject调用失败,它可能永远不会被分配,但错误代码不是unchecked((int)0x800401E3)

当您第一次声明oWord时,需要将其设置为:

Microsoft.Office.Interop.Word._Application oWord = null;

Microsoft.Office.Interop.Word._Application oWord = new Microsoft.Office.Interop.Word.Application();

我可能会做后者。这也消除了对null检查的需求,现在你真的应该这样做,因为如果在try/catch块中捕获到异常,你不会完全中止。

(话虽如此,如果这样做实际上会启动Word(如果它还没有运行(,那么使用第一个选项,然后确保oWord在try/catch之后不是仍然为null。(

Microsoft.Office.Interop.Word._Application oWord; 
try
{
    oWord = Marshal.GetActiveObject("Word.Application") as
        Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
    if (ce.ErrorCode == unchecked((int)0x800401E3))
        oWord = new Microsoft.Office.Interop.Word.Application();
}
oWord.ScreenUpdating = false;

让我们来看看为什么编译器告诉您,在执行此代码后可能不会分配oWord

  1. 如果try内部的代码执行时没有异常,则必须分配oWord
  2. 或者,如果该代码引发异常,则可能无法处理,在这种情况下,它会传播到上面的代码之外
  3. 或者,如果try中的代码抛出COMException,它将被捕获。如果错误代码是0x800401E31,则分配oWord
  4. 或者,如果错误代码不是0x800401E3,则永远不会分配oWord

我们可以对您的代码进行注释,以更清楚地证明这一点:

Microsoft.Office.Interop.Word._Application oWord; 
try
{
    oWord = Marshal.GetActiveObject("Word.Application") as
        Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
    // oWord still not initialized ....
    if (ce.ErrorCode == unchecked((int)0x800401E3))
        oWord = new Microsoft.Office.Interop.Word.Application();
    else
        ; // .... and still not initialized ....
}
oWord.ScreenUpdating = false;

在我看来,处理这个问题最简单的方法就是重新抛出异常。

Microsoft.Office.Interop.Word._Application oWord; 
try
{
    oWord = Marshal.GetActiveObject("Word.Application") as
        Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
    if (ce.ErrorCode != unchecked((int)0x800401E3))
        throw;
    oWord = new Microsoft.Office.Interop.Word.Application();
}
oWord.ScreenUpdating = false;

这避免了将变量初始化为null并随后测试其是否仍为null的需要。

更重要的是,它明确地处理代码无法处理的错误条件。即CCD_ 15以外的COM错误。

只需为其分配一个默认的null值:

Microsoft.Office.Interop.Word._Application oWord = null;

这是必要的,因为代码当前在catch{}块的if statement中为其分配了一个值,所以oWord可能永远不会得到没有初始值/默认值的值。