예외 Throw
멤버가 수행하도록 디자인된 작업을 성공적으로 수행할 수 없는 경우 예외가 throw되는데. 이를 실행 실패라고 합니다. 예를 들어, Connect 메서드가 지정한 원격 끝점으로 연결될 수 없는 경우 이를 실행 오류라고 하며 예외가 throw됩니다.
다음 지침은 적절한 경우에 예외를 throw하는 데 도움이 됩니다.
오류 코드를 반환하지 않습니다. 예외는 프레임워크에서 오류를 보고하는 기본 방법입니다.
예외 디자인 지침에서 예외를 사용하여 얻을 수 있는 이점에 대해 설명합니다.
예외를 throw하여 실행 실패를 보고합니다. 멤버가 수행하도록 디자인된 작업을 성공적으로 수행할 수 없는 경우 실행 실패로 간주되고 예외가 throw됩니다.
코드가 실행을 계속하면 안전하지 않게 되는 경우 예외를 throw하는 대신 System.Environment.FailFast(System.String)(.NET Framework 버전 2.0 기능)를 호출하여 프로세스를 종료할 수 있습니다.
가능하면 정상적인 제어 흐름에는 예외를 사용하지 않습니다. 잠재적인 경합 상태가 있는 시스템 실패 및 작업을 제외하고, 프레임워크 디자이너는 사용자가 예외를 throw하지 않는 코드를 작성할 수 있도록 API를 디자인해야 합니다. 예를 들어, 사용자가 예외를 throw하지 않는 코드를 작성할 수 있도록 멤버를 호출하기 전에 사전 조건을 확인하는 방법을 제공할 수 있습니다.
다음 코드 예제에서는 메시지 문자열이 null(Visual Basic의 경우 Nothing)인 경우 예외가 throw되는 않도록 테스트하는 방법을 보여 줍니다.
Public Class Doer
' Method that can potential throw exceptions often.
Public Shared Sub ProcessMessage(ByVal message As String)
If (message = Nothing) Then
Throw New ArgumentNullException("message")
End If
End Sub
' Other methods...
End Class
Public Class Tester
Public Shared Sub TesterDoer(ByVal messages As ICollection(Of String))
For Each message As String In messages
' Test to ensure that the call
' won't cause the exception.
If (Not (message) Is Nothing) Then
Doer.ProcessMessage(message)
End If
Next
End Sub
End Class
public class Doer
{
// Method that can potential throw exceptions often.
public static void ProcessMessage(string message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
}
// Other methods...
}
public class Tester
{
public static void TesterDoer(ICollection<string> messages)
{
foreach (string message in messages)
{
// Test to ensure that the call
// won't cause the exception.
if (message != null)
{
Doer.ProcessMessage(message);
}
}
}
}
public ref class Doer
{
public:
// Method that can potential throw exceptions often.
static void ProcessMessage(String^ message)
{
if (message == nullptr)
{
throw gcnew ArgumentNullException("message");
}
}
// Other methods...
};
public ref class Tester
{
public:
static void TesterDoer(ICollection<String^>^ messages)
{
for each (String^ message in messages)
{
// Test to ensure that the call
// won't cause the exception.
if (message != nullptr)
{
Doer::ProcessMessage(message);
}
}
}
};
throw되는 예외 수를 줄일 수 있는 디자인 패턴에 대한 자세한 내용은 예외 및 성능을 참조하십시오.
예외가 throw될 때 성능에 주는 영향을 고려합니다.
시스템 실패가 아닌 멤버 계약의 위반으로 인해 공개적으로 호출할 수 있는 멤버가 throw한 모든 예외는 문서화하여 계약의 일부로 처리합니다. 계약의 일부인 예외는 한 버전에서 다음 버전으로 변경할 수 없습니다.
일부 옵션에 따라 예외를 throw하거나 throw하지 않을 수 있는 공용 멤버를 소유하지 않습니다.
예를 들어, 다음과 같은 멤버는 정의하지 않습니다.
Private Function ParseUri(ByVal uriValue As String, ByVal throwOnError As Boolean) As Uri
Uri ParseUri(string uriValue, bool throwOnError)
Uri^ ParseUri(String^ uriValue, bool throwOnError)
예외를 반환 값 또는 out 매개 변수로 반환하는 공용 멤버를 소유하지 않습니다.
이 지침은 공개적으로 표시되는 멤버를 위한 것입니다. 전용 도우미 메서드를 사용하여 예외를 생성하고 초기화하는 것은 허용됩니다.
예외 작성기 메서드를 사용할 수 있습니다. 일반적으로 같은 예외를 다른 장소에서 throw합니다. 코드를 많이 사용하지 않으려면 예외를 만들고 해당 속성을 초기화하는 도우미 메서드를 사용합니다.
도우미 메서드는 예외를 throw하지 않아야 합니다. 그렇지 않으면 스택 추적이 예외를 발생시킨 호출 스택을 정확히 반영하지 않습니다.
예외 필터 블록에서 예외를 throw하지 않습니다. 예외 필터에서 예외가 발생하면 CLR(공용 언어 런타임)에 의해 이 예외가 catch되고 필터에서 false를 반환합니다. 이 동작은 필터 실행과 false 반환 간에 명시적으로 구별할 수 없으므로 디버깅하기 매우 어렵습니다.
C#과 같은 일부 언어에서는 예외 필터를 지원하지 않습니다.
finally 블록에서 명시적으로 예외를 throw하지 않습니다. throw한 메서드를 호출하면 예외가 암시적으로 throw될 수 있습니다.
Portions Copyright 2005 Microsoft Corporation. All rights reserved.
Portions Copyright Addison-Wesley Corporation. All rights reserved.
디자인 지침에 자세한 내용은 참조를 "Framework 디자인 지침: 규칙, 숙어, 및 재사용에 대 한 패턴입니다.NET 라이브러리"도 서 Krzysztof Cwalina와 Brad Abrams, 게시 Addison-wesley, 2005.