다음을 통해 공유


try-catch(C# 참조)

업데이트: 2007년 11월

try-catch 문은 try 블록과 각각 다른 예외의 처리기를 지정하는 하나 이상의 catch 절로 구성됩니다. 예외가 throw될 경우 CLR(공용 언어 런타임)에서는 이 예외를 처리하는 catch 문을 찾습니다. 현재 실행되고 있는 메서드에 catch 블록이 없는 경우 CLR은 현재 메서드를 호출한 메서드를 찾는 방법으로 호출 스택을 조사합니다. catch 블록을 찾지 못하면 CLR은 사용자에게 처리되지 않은 예외 메시지를 표시하고 프로그램 실행을 중지합니다.

try 블록에는 예외를 발생시킬 수 있는 보호된 코드가 포함됩니다. 이 블록은 예외가 throw되거나 성공적으로 완료될 때까지 실행됩니다. 예를 들어, 다음 예제와 같이 null 개체를 캐스팅하려고 하면 NullReferenceException 예외가 발생합니다.

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 문을 catch 블록에 사용하여 catch 문에서 catch한 예외를 다시 throw할 수 있습니다. 예를 들면 다음과 같습니다.

catch (InvalidCastException e) 
{
    throw (e);    // Rethrowing exception e
}

새 예외를 throw할 수도 있습니다. 이렇게 할 경우 catch한 예외를 내부 예외로 지정합니다.

catch (InvalidCastException e) 
{
   // Can do cleanup work here.
    throw new CustomException("Error message here.", e);
}

현재 매개 변수가 없는 catch 절로 처리된 예외를 다시 throw하려면 인수 없이 throw 문을 사용합니다. 예를 들면 다음과 같습니다.

catch
{
    throw;
}

try 블록 내에서는 이 블록에서 선언된 변수만 초기화하십시오. 그렇지 않으면 블록 실행이 완료되기 전에 예외가 발생할 수 있습니다. 예를 들어 다음 코드 예제에서는 변수 x가 try 블록 내에서 초기화됩니다. Write(x) 문의 try 블록 외부에서 이 변수를 사용하려고 하면 할당되지 않은 지역 변수를 사용했습니다.라는 컴파일 오류가 발생합니다.

static void Main() 
{
    int x;
    try 
    {
        // Don't initialize this variable here.
        x = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'x'.
    Console.Write(x);
}

catch에 대한 자세한 내용은 try-catch-finally를 참조하십시오.

예제

다음 예제의 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);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */

아래 예제에서는 두 개의 catch 문을 사용합니다. 앞에 나오는 더 구체적인 예외가 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 TryFinallyTest.Main() First exception caught.
*/

앞의 예제에서 가장 구체적이지 않은 catch 절을 사용하면 다음과 같은 오류 메시지가 나타납니다.

A previous catch clause already catches all exceptions of this or a super type ('System.Exception')

하지만 throw 문을 아래와 같은 형식으로 바꾸면 가장 구체적이지 않은 예외를 catch할 수 있습니다.

throw new Exception();

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 단원을 참조하십시오.

  • 5.3.3.13 Try-catch 문

  • 8.10 try 문

  • 16 예외

참고 항목

작업

방법: 명시적으로 예외 Throw

개념

C# 프로그래밍 가이드

참조

C# 키워드

The try, catch, and throw Statements

예외 처리문(C# 참조)

throw(C# 참조)

try-finally(C# 참조)

기타 리소스

C# 참조