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

时间:2014-06-30 19:37:45

标签: c# .net interop

我正在使用以下代码来获取正在运行的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..Catch块并说我已取消分配 oWord

那么分配这个的正确方法是什么?

3 个答案:

答案 0 :(得分:6)

如果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();

我可能会做后者。这也消除了在线下进行空检查的需要,现在你真的应该拥有,因为如果在try / catch块中捕获到异常,你就不会完全中止。

(话虽如此,如果这样做实际上会启动Word,如果它尚未运行,请使用第一个选项,然后确保oWord在尝试后为空/捕获)。

答案 1 :(得分:2)

只需为其指定默认值null

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

这是必要的,因为代码当前在catch {}块的if statement中为其赋值,因此oWord可能永远不会获得没有初始值/默认值的值。

答案 2 :(得分:2)

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
  5. 我们可以对您的代码进行注释,以便更清楚地证明这一点:

    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

    它还明确地处理了代码无法处理的错误情况。即MK_E_UNAVAILABLE以外的COM错误。