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
那么,正确的分配方式是什么呢?
如果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
。
- 如果
try
内部的代码执行时没有异常,则必须分配oWord
- 或者,如果该代码引发异常,则可能无法处理,在这种情况下,它会传播到上面的代码之外
- 或者,如果try中的代码抛出
COMException
,它将被捕获。如果错误代码是0x800401E31
,则分配oWord
- 或者,如果错误代码不是
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
可能永远不会得到没有初始值/默认值的值。