try 블록은 C# 프로그래머가 예외의 영향을 받을 수 있는 코드를 분할하는 데 사용됩니다. 연결된 catch 블록은 결과 예외를 처리하는 데 사용됩니다.
finally 블록에는 try
블록에서 예외가 발생하든 발생하지 않든 실행되는 코드가 포함됩니다. 예를 들어 try
블록에 할당된 리소스를 해제하는 코드가 포함될 수 있습니다.
try
블록에는 하나 이상의 연결된 catch
블록 또는 finally
블록 또는 둘 다 필요합니다.
다음 예제는 try-catch
문, try-finally
문, 그리고 try-catch-finally
문을 보여줍니다.
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
// Only catch exceptions that you know how to handle.
// Never catch base class System.Exception without
// rethrowing it at the end of the catch block.
}
try
{
// Code to try goes here.
}
finally
{
// Code to execute after the try block goes here.
}
try
{
// Code to try goes here.
}
catch (SomeSpecificException ex)
{
// Code to handle the exception goes here.
}
finally
{
// Code to execute after the try (and possibly catch) blocks
// goes here.
}
try
블록이 catch
또는 finally
블록 없이 있을 경우 컴파일러 오류가 발생합니다.
Catch 블록
블록은 catch
잡을 예외의 유형을 지정할 수 있습니다. 형식 사양을 예외 필터라고 합니다. 예외 형식은 .에서 Exception파생되어야 합니다. 일반적으로 블록에서 throw Exception 될 수 있는 모든 예외를 처리하는 방법을 알고 있거나 블록 끝에 try
문을 포함하지 않는 한 예외 필터로 throw
지정 catch
하지 마세요.
서로 다른 예외 클래스가 있는 여러 catch
블록을 함께 연결할 수 있습니다. 코드에서 catch
블록은 위에서 아래로 평가되지만, throw된 각 예외에 대해서는 하나의 catch
블록만 실행됩니다. throw된 예외의 정확한 형식 또는 기본 클래스를 지정하는 첫 번째 catch
블록이 실행됩니다. 일치하는 예외 클래스가 catch
블록에서 지정되지 않은 경우, 문에 형식이 없는 블록이 있는 경우 catch
블록이 선택됩니다. 가장 구체적인(즉, 가장 파생된) 예외 클래스를 먼저 사용하여 블록을 배치 catch
하는 것이 중요합니다.
다음 조건이 true인 경우 예외를 catch합니다.
- 예외가 발생할 수 있는 이유를 잘 이해하고 있으며, 개체를 catch할 때 사용자에게 새 파일 이름을 입력하라는 메시지를 표시하는 것과 같이 특정 복구를 FileNotFoundException 구현할 수 있습니다.
- 보다 구체적인 새 예외를 만들고 throw할 수 있습니다.
int GetInt(int[] array, int index) { try { return array[index]; } catch (IndexOutOfRangeException e) { throw new ArgumentOutOfRangeException( "Parameter index is out of range.", e); } }
- 더 많은 처리를 위해 예외를 전달하기 전에 부분적으로 처리하려고 합니다. 다음 예제에서는 예외를 다시 발생시키기 전에 오류 로그에 기록을 추가하는 데
catch
블록이 사용됩니다.try { // Try to access a resource. } catch (UnauthorizedAccessException e) { // Call a custom error logging procedure. LogError(e); // Re-throw the error. throw; }
예외 필터를 지정하여 catch 절에 부울 식을 추가할 수도 있습니다. 예외 필터는 특정 catch 절이 해당 조건이 true일 때만 일치함을 나타냅니다. 다음 예제에서 두 catch 절은 동일한 예외 클래스를 사용하지만 다른 오류 메시지를 만들기 위해 추가 조건이 선택됩니다.
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch (IndexOutOfRangeException e) when (index < 0)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be negative.", e);
}
catch (IndexOutOfRangeException e)
{
throw new ArgumentOutOfRangeException(
"Parameter index cannot be greater than the array size.", e);
}
}
항상 반환 false
되는 예외 필터를 사용하여 모든 예외를 검사하지만 처리할 수는 없습니다. 일반적인 사용은 예외를 기록하는 것입니다.
public class ExceptionFilter
{
public static void Main()
{
try
{
string? s = null;
Console.WriteLine(s.Length);
}
catch (Exception e) when (LogException(e))
{
}
Console.WriteLine("Exception must have been handled");
}
private static bool LogException(Exception e)
{
Console.WriteLine($"\tIn the log routine. Caught {e.GetType()}");
Console.WriteLine($"\tMessage: {e.Message}");
return false;
}
}
메서드는 항상 LogException
를 반환하며, 이 예외 필터를 사용하는 false
절과 일치하지 않습니다. catch 절은 일반적일 수 있으며, System.Exception이후 절은 보다 구체적인 예외 클래스를 처리할 수 있습니다.
최종적으로 블록
finally
블록을 사용하면 try
블록에서 수행된 작업을 정리할 수 있습니다. 있는 경우, finally
블록은 try
블록 및 일치하는 catch
블록 이후에 마지막으로 실행됩니다.
finally
블록은 예외가 발생하거나 catch
예외 유형에 맞는 블록이 발견되든 관계없이 항상 실행됩니다.
블록은 finally
런타임 내 가비지 수집기가 개체를 종료하는 것을 기다리지 않고 파일 스트림, 데이터베이스 연결, 그래픽 핸들 등과 같은 리소스를 해제할 수 있도록 사용할 수 있습니다.
다음 예제에서는 finally
블록에서 열리는 파일을 닫기 위해 try
블록이 사용됩니다. 파일을 닫기 전에 파일 핸들의 상태를 확인합니다. 블록에서 try
파일을 열 수 없는 경우 파일 핸들에는 여전히 값 null
이 있으며 블록은 finally
파일을 닫으려고 시도하지 않습니다. 대신 try
블록에서 파일이 성공적으로 열리면, finally
블록이 열린 파일을 닫습니다.
FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try
{
file = fileinfo.OpenWrite();
file.WriteByte(0xF);
}
finally
{
// Check for null because OpenWrite might have failed.
file?.Close();
}
C# 언어 사양
자세한 내용은 C# 언어 사양의 예외 및 try 문을 참조하세요. 언어 사양은 C# 구문 및 사용의 최종 소스입니다.
참고하십시오
.NET