English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# 예외 처리

여기서는 C#에서 try, catch 및 finally 블록을 사용하여 예외 처리를 배우는 것을 배웁니다.

프로그램이 충돌하고 예상치 못한 결과를 발생시키는 것을 방지하기 위해, 예외를 처리해야 합니다. C#은 try, catch, finally 블록을 사용하여 예외를 처리하는 내장 지원을 제공합니다.

문법:

try
{
    // 여기에 코드를 넣으면 예외가 발생할 수 있습니다
}
catch
{
    // 여기서 예외를 처리
}
finally
{
    // 최종 정리 코드
}

try 블록:예외를 발생시킬 가능성이 있는 의심스러운 코드는 try{ } 블록에 위치해야 합니다. 실행 중에 예외가 발생하면 제어 흐름은 첫 번째 일치하는 catch 블록으로 이동합니다.

catch 블록:catch 블록은 예외 처리 프로그램 블록으로, 예외를 기록하고 검토할 수 있는 작업을 수행할 수 있습니다. catch 블록은 예외 타입의 파라미터를 사용하며, 이 파라미터를 사용하여 예외의 상세 정보를 얻을 수 있습니다.

finally 블록:finally는 예외가 발생하든 발생하지 않든 항상 해당 블록을 수행합니다. 일반적으로 finally는 자원을 해제하는 블록을 사용해야 합니다. 예를 들어, try 블록에서 열린 모든 스트림이나 파일 객체를 닫습니다.

비数字经济 문자를 입력하면 다음과 같은 예외가 발생할 수 있습니다.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter a number: ");
        var num = int.Parse(Console.ReadLine());
        Console.WriteLine($"{num}의 제곱은 {num}"); * num");
    }
}

위의 예제에서 가능한 예외를 처리하려면 코드를 try 블록에 포장하고, 다음과 같이 catch 블록에서 예외를 처리하십시오.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Enter a number: ");
            var num = int.parse(Console.ReadLine());
            Console.WriteLine($"{num}의 제곱은 {num}"); * num");
        }
        catch
        {
            Console.Write("Error occurred.");
        }
        finally
        {
            Console.Write("Re");-try with a different number.");
        }
    }
}

위의 예제에서는 이 코드를 try 블록에 포장했습니다. try 블록 내에서 예외가 발생하면 프로그램은 해당 catch 블록으로 이동합니다. catch 블록 내에서는 사용자에게 오류에 대한 정보를 표시하며, finally 블록 내에서는 프로그램이 실행된 후에 대한 작업을 표시합니다.

try 블록은 catch 또는 finally 또는 두 블록 모두를 따라야 합니다. try 블록에서 catch 또는 finally 블록을 사용하지 않으면 컴파일 시 오류가 발생합니다.

이상적인 경우, catch 블록은 내장이나 사용자 정의 예외 클래스의 파라미터를 포함하여 오류 정보를 얻기 위해해야 합니다. 다음은 모든 유형의 예외를 포착하는 Exception 타입의 파라미터를 포함하고 있습니다.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Console.WriteLine("Enter a number: ");
            var num = int.parse(Console.ReadLine());
            Console.WriteLine($"{num}의 제곱은 {num}"); * num");
        }
        catch(Exception ex)
        {
            Console.Write("Error info:"); + ex.Message);
        }
        finally
        {
            Console.Write("Re");-try with a different number.");
        }
    }
}

예외 필터

catch에 다른 예외 유형 파라미터를 가진 여러 블록을 사용할 수 있습니다. 이를 예외 필터라고 합니다. 다른 방식으로 다른 예외 유형을 처리하고자 할 때 예외 필터가 매우 유용합니다.

class Program
{
    static void Main(string[] args)
    {
        Console.Write("Please enter a number to divide 100: ");
        
        try
        {
            int num = int.Parse(Console.ReadLine());
            int result = 100 / num;
            Console.WriteLine("100 / {0} = {1};
        }
        catch(DivideByZeroException ex)
        {
            Console.Write("0으로 나눌 수 없습니다. 다시 시도해 주세요.");
        }
        catch(InvalidOperationException ex)
        {
            Console.Write("유효하지 않은 작업입니다. 다시 시도해 주세요.");
        }
        catch(FormatException      ex)
        {
            Console.Write("유효한 형식이 아닙니다. 다시 시도해 주세요.");
        }
        catch(Exception      ex)
        {
            Console.Write("에러가 발생했습니다! 다시 시도해 주세요.");
        }
    }
}

위의 예제에서는 catch에 다른 예외 유형을 가진 여러 블록을 지정했습니다. 따라서 사용자에게 적절한 메시지를 표시할 수 있어 사용자가 동일한 오류를 다시 반복하지 않도록 할 수 있습니다.

주의:
동일한 예외 유형의 여러 catch 블록을 허용하지 않습니다. 기본 예외 유형을 가진 catch 블록은 마지막 블록이어야 합니다.

잘못된 catch 블록

동일한 try..catch 문에서 파라미터 없는 catch 블록과 Exception 파라미터를 가진 catch 블록을 사용할 수 없습니다. 왜냐하면 두 블록이 동일한 작업을 수행하기 때문입니다.

try
{
    //예외를 일으킬 수 있는 코드
}
catch //catch와 catch(Exception 异常)는 동시에 존재할 수 없습니다.
{ 
    Console.WriteLine("Exception occurred");
}
catch(Exception ex) //catch와 catch(异常异常)는 동시에 존재할 수 없습니다.
{
    Console.WriteLine("Exception occurred");
}

또한, 파라미터 없는 catch 블록 catch {} 또는 일반 catch 블록 catch (Exception ex){}은 마지막 블록이어야 합니다. catch {} 또는 catch (Exception ex) 블록 이후에 다른 catch 블록이 있다면 컴파일러는 오류를 발생시킵니다.

    예제: 잘못된 catch 잡기

try
{
    //예외를 일으킬 수 있는 코드
}
catch
{ 
    // 이 캡처 블록은 마지막 블록이어야 합니다
}
catch(NullReferenceException nullEx)
{
    Console.WriteLine(nullEx.Message);
}
catch(InvalidCastException inEx)
{
    Console.WriteLine(inEx.Message);
}

finally 블록

finally 블록은 선택적인 블록으로, try 또는 catch 블록 이후에 위치해야 합니다. 예외가 발생했与否를 불문하고, always finally 블록이 실행됩니다. finally 블록은 일반적으로 비투스드 오브젝트를 처리하는 등의 클리닝 코드에 사용됩니다.

    예제: finally 블록

static void Main(string[] args)
{
    FileInfo file = null;
    try
    {
        Console.Write("쓰기할 파일 이름을 입력하세요: ");
        string fileName = Console.ReadLine();
        file = new FileInfo(fileName);
        file.AppendText("Hello World!");
    }
    catch(Exception ex)
    {
        Console.WriteLine("오류가 발생했습니다: {0}", ex.Message);
    }
    finally
    {
        // 여기서 파일 객체를 정리합니다;
        file = null;
    }
}
finally는 사용할 수 없습니다 여러 블록. 또한, finally 블록은 return, continue, 또는 break 키워드를 포함할 수 없습니다. finally 블록을 벗어나는 제어를 허용하지 않습니다.

내부 try-catch

C#는 내부 try를 허용합니다-catch 블록에서-catch 블록에서 예외가 발생하면, 예외가 발생한 catch 블록 이후의 첫 번째 일치하는 블록에서 예외를 잡습니다.

static void Main(string[] args)
{
    var divider = 0;
    try
    {
        try
        {
            var result = 100/divider;
        }
        catch
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Outer catch");
    }
}
출력:
Inner catch

위 예제에서 catch 블록은 모든 예외 타입을 처리하는 첫 번째 블록이기 때문에 내부 블록을 실행합니다.

내부 catch 블록과 일치하는 예외 타입이 없으면, 제어가 외부 catch 블록으로 이동하여 적절한 예외 필터를 찾을 때까지 이동합니다. 아래 예제를 참조하세요.

static void Main(string[] args)
{
    var divider = 0;
    try
    {
        try
        {
            var result = 100/divider;
        }
        catch(NullReferenceException ex)
        {
            Console.WriteLine("Inner catch");
        }
    }
    catch
    {
        Console.WriteLine("Outer catch");
    }
}
출력:
Outer catch

위의 예제에서 DivideByZeroException 타입의 예외가 발생합니다. 내부 catch 블록은 NullReferenceTypeException만 처리하므로 외부 catch 블록이 처리합니다.