try-catch (C# 參考)
更新:2010 年 7 月
try-catch 陳述式是由其後跟隨一個或多個 catch 子句的 try 區塊組成,以指定不同例外狀況的處理常式。 擲回例外狀況時,Common Language Runtime (CLR) 會尋找處理此例外狀況的 catch 陳述式。 如果目前執行的方法未包含這種 catch 區塊,CLR 會檢查呼叫目前方法的方法,一直向上檢查至呼叫堆疊。 如果找不到 catch 區塊,CLR 就會顯示未處理的例外狀況訊息以告知使用者,並停止執行程式。
try 區塊中含有可能會導致例外狀況並受到嚴密監控的程式碼。 執行區塊直到擲回例外狀況或已成功完成。 例如,以下轉換 null 物件的嘗試會引發 NullReferenceException 例外狀況:
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
雖然 catch 子句可在無引數的情況下使用來呼叫任何類型的例外狀況,但不建議這種用法。 一般來說,您應該只攔截那些您知道如何復原的例外狀況。 因此,您一定要指定衍生自 System.Exception 的物件引數,例如:
catch (InvalidCastException e)
{
}
在相同的 try-catch 陳述式中,有可能使用一個以上特定 catch 子句。 此時由於 catch 子句是依照順序進行檢查,因此 catch 子句的順序就非常重要。 在較不特定的例外狀況之前攔截較特定的例外狀況。 如果因 catch 區塊順序而導致永遠無法執行到後面的區塊,編譯器會產生錯誤。
throw 陳述式可以用於 catch 區塊中,以重新擲回 catch 陳述式所攔截的例外狀況。 下列範例會從 IOException 例外狀況中擷取來源資訊,然後將例外狀況擲回到父方法。
catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
// Extract some information from this exception, and then
// throw it to the parent method.
if (e.Source != null)
Console.WriteLine("IOException source: {0}", e.Source);
throw;
}
您可以攔截一個例外狀況,並擲回不同的例外狀況。 當您這樣做時,請指定您當做內部例外狀況攔截到的例外狀況,如下列範例中所示。
catch (InvalidCastException e)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", e);
}
當指定的條件為 true 時,您也可以重新擲回例外狀況,如下列範例中所示。
catch (InvalidCastException e)
{
if (e.Data == null)
{
throw;
}
else
{
// Take some action.
}
}
從 try 區塊內部,指初始化在此宣告的變數。 否則,區塊執行完成前可能會發生例外狀況。 例如下列程式碼範例中的 n 變數就是在 try 區塊中進行初始化。 Write(n) 陳述式中,如果嘗試在 try 區塊外面使用這個變數,會產生以下編譯器錯誤。
static void Main()
{
int n;
try
{
// Do not initialize this variable here.
n = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'n'.
Console.Write(n);
}
如需 catch 的詳細資訊,請參閱 try-catch-finally。
範例
在下列範例中,try 區塊包含 ProcessString 方法的呼叫,這個呼叫可能會造成例外狀況。 catch 子句包含只會在畫面上顯示訊息的例外狀況處理常式 (Exception Handler)。 從 MyMethod 內部呼叫 throw 陳述式時,系統會尋找 catch 陳述式並且顯示 Exception caught 訊息。
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
string s = null; // For demonstration purposes.
try
{
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() Exception caught.
* */
在這個範例中,使用兩個 catch 陳述式。 會攔截最特定的例外狀況 (會先出現)。
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}
static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/
在上述範例中,如果您以最不特定的 catch 子句開始,就會收到錯誤訊息:
A previous catch clause already catches all exceptions of this or a super type ('System.Exception')
但是為了攔截最不特定的例外狀況,將 throw 陳述式用下列來取代:
throw new Exception();
C# 語言規格
如需詳細資訊,請參閱 C# 語言規格。 語言規格是 C# 語法和用法的決定性來源。
請參閱
工作
參考
try, catch, and throw Statements (C++)
概念
其他資源
變更記錄
日期 |
記錄 |
原因 |
---|---|---|
2010 年 7 月 |
已更新 throw 範例。 |
客戶回函。 |