|
|
|
object o2 = null; try { int i2 = (int)o2; // Error } |
catch 절을 인수 없이 사용하여 모든 형식의 예외를 catch할 수 있지만 이러한 방법은 권장되지 않습니다. 일반적으로 복구할 수 있는 예외만 catch해야 합니다. 따라서 다음 예제와 같이 항상 System.Exception에서 파생된 개체 인수를 지정해야 합니다.
|
catch (InvalidCastException e) { |
같은 try-catch 문에서 여러 개의 특정 catch 절을 사용할 수 있습니다. catch 절은 순서대로 검사되므로 이런 경우에는 catch 절의 순서가 중요합니다. 보다 구체적인 예외를 먼저 catch하십시오. 나중에 블록 전혀 연결할 수 있도록 해당 catch 블록의 순서를 않으면 컴파일러에서 오류가 발생합니다.
Throw는 re-throw에 의해 발생한 예외 블록이 있는 catch문을 catch문으로 사용 될 수 있습니다. 다음은 원본 정보를 추출하는 에서 IOException, 예외 및 부모 메서드를. 예외를 throw하는 소스 코드 입니다.
|
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하고 다른 예외를 throw할 수 있습니다. 이렇게 하면 다음 예제와 같이 내부 예외로 발생한 예외를 지정하십시오.
|
catch (InvalidCastException e) { // Perform some action here, and then throw a new exception. throw new YourCustomException("Put your error message here.", e); } |
지정한 조건이 참일 경우 다음 예제와 같을 때 예외가 re-throw될 수도 있습니다.
|
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); } |
예제 소스
다음 예제에서는 try차단 호출이 포함되어 있는 ProcessString메서드가 있는 발생할 예외입니다. catch 절에는 단순히 화면에 메시지를 표시하는 예외 처리기가 포함되어 있습니다. 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); } } } |
출력 결과
아래 예제에서는 두 개의 catch 문을 사용합니다. 앞에 나오는 더 구체적인 예외가 catch됩니다.
|
class ThrowTest2 { 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); } } } |
출력 결과
앞의 예제에서 가장 구체적이지 않은 catch 절을 사용하면 다음과 같은 오류 메시지가 나타납니다.
|
A previous catch clause already catches all exceptions of this or a super type ('System.Exception') |
하지만 throw 문을 아래와 같은 형식으로 바꾸면 가장 구체적이지 않은 예외를 catch할 수 있습니다.
|
throw new Exception(); |
try-catch-finally 일반적으로 catch와 finally를 함께 사용하여 try 블록에서 리소스를 가져와 사용하고 catch 블록에서 예외 상황을 처리한 다음, finally 블록에서 리소스를 해제합니다.
class Program { static void Main(string[] args) { try { Console.WriteLine("Executing the try statement."); throw new NullReferenceException(); } catch (NullReferenceException e) { Console.WriteLine("{0} Caught exception #1.", e); } catch { Console.WriteLine("Caught exception #2."); } finally { Console.WriteLine("Executing finally block."); } } }
결과 화면
try-finally
finally 블록은 try 블록에서 할당된 리소스를 정리하고 예외 발생 여부에 관계없이 항상 실행해야 하는 코드를 실행하는 데 유용합니다. try 블록이 종료되는 방법에 관계없이 항상 제어가 finally 블록으로 전달됩니다.
catch는 문 블록에서 발생하는 예외를 처리하는 데 사용되지만 finally는 앞에 나오는 try 블록의 종료 방법에 관계없이 코드의 문 블록이 반드시 실행되도록 하는 데 사용됩니다.
예제 소스
아래 예제에는 예외를 발생시키는 잘못된 변환문이 하나 있습니다. 프로그램을 실행하면 런타임 오류 메시지가 나타나지만 finally 절이 계속 실행되어 출력이 표시됩니다.
|
class Program { static void Main(string[] args) { int i = 123; string s = "Some string"; object o = s;
try { // Invalid conversion; o contains a string not an int i = (int)o; } finally { Console.Write("i = {0}", i); } } } |
결과 화면