관리 코드의 어설션

어설션 또는 Assert 문은 Assert 문에 대한 인수로 지정하는 조건을 테스트합니다. 조건이 true로 평가되면 동작이 발생하지 않고, 조건이 false로 평가되면 어설션이 실패합니다. 디버그 빌드로 실행 중인 경우 프로그램 중단 모드가 시작됩니다.

항목 내용

System.Diagnostics 네임스페이스의 어설션

Debug.Assert 메서드

Debug.Assert의 파생 작업

Trace 및 Debug 요구 사항

어설션 인수

어설션 동작 사용자 지정

구성 파일에서 어설션 설정

System.Diagnostics 네임스페이스의 어설션

Visual Basic 및 Visual C#에서는 Assert 네임스페이스에 있는 Debug 또는 Trace에서 System.Diagnostics 메서드를 사용할 수 있습니다. Debug 클래스 메서드는 프로그램의 릴리스 버전에 포함되지 않으므로 릴리스 코드의 크기를 증가시키거나 속도를 떨어뜨리지 않습니다.

C++는 Debug 클래스 메서드를 지원하지 않습니다. 조건부 컴파일(예: #ifdef DEBUG... #endif)에 Trace 클래스를 사용하면 동일한 결과를 얻을 수 있습니다.

항목 내용

Debug.Assert 메서드

코드가 정확한 경우 true로 유지되어야 하는 조건을 테스트하려면 System.Diagnostics.Debug.Assert 메서드를 사용합니다. 예를 들어 정수 나누기 함수를 작성한 경우, 수학의 규칙에 따라 0으로는 나눌 수 없습니다. 다음과 같이 어설션을 사용하여 이를 테스트할 수 있습니다.

Function IntegerDivide(ByVal dividend As Integer, ByVal divisor As Integer) As Integer
    Debug.Assert(divisor <> 0)
    Return CInt(dividend / divisor)
End Function
int IntegerDivide ( int dividend , int divisor )
{
    Debug.Assert ( divisor != 0 );
    return ( dividend / divisor );
}

디버거에서 이 코드를 실행하면 어설션 문이 평가되지만, 릴리스 버전에서는 비교가 실행되지 않으므로 추가 오버헤드가 없습니다.

또는 다음과 같은 예도 있습니다. 다음과 같이 당좌 예금 계좌를 구현하는 클래스가 있다고 가정합니다.

Dim amount, balance As Double
balance = savingsAccount.balance
Debug.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

계좌에서 돈을 인출하기 전에 인출하려는 금액 이상의 잔액이 있는지 확인해야 합니다. 다음과 같은 어설션을 작성하여 잔액을 확인할 수 있습니다.

Dim amount, balance As Double
balance = savingsAccount.balance
Trace.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );

작성한 코드로 릴리스 버전을 만들면 System.Diagnostics.Debug.Assert 메서드에 대한 호출이 사라집니다. 즉, 릴리스 버전에서는 잔액을 확인하는 호출이 사라집니다. 이 문제를 해결하려면 System.Diagnostics.Debug.Assert 대신 릴리스 버전에서 사라지지 않는 System.Diagnostics.Trace.Assert를 사용해야 합니다.

System.Diagnostics.Trace.Assert 호출과 달리 System.Diagnostics.Debug.Assert 호출은 릴리스 버전에 오버헤드를 추가합니다.

항목 내용

Debug.Assert의 파생 작업

System.Diagnostics.Debug.Assert를 사용할 때는 Assert가 제거되어도 Assert 내의 코드에 의해 프로그램의 결과가 변경되지 않도록 해야 합니다. 프로그램 결과가 변경되면 릴리스 버전의 프로그램에만 나타나는 버그가 발생할 수 있습니다. 특히 다음 예와 같이 함수 또는 프로시저 호출이 포함된 Assert를 사용할 경우에 주의해야 합니다.

' unsafe code
Debug.Assert (meas(i) <> 0 )
// unsafe code
Debug.Assert (meas(i) != 0 );

이러한 System.Diagnostics.Debug.Assert의 사용이 안전해 보일 수도 있지만 meas 함수가 호출될 때마다 카운터를 업데이트한다고 가정해 보십시오. 릴리스 버전을 빌드할 때 이 meas에 대한 호출이 제거되므로 카운터는 업데이트되지 않습니다. 이는 파생 작업이 있는 함수의 예입니다. 파생 작업이 있는 함수에 대한 호출을 제거하면 릴리스 버전에서만 나타나는 버그가 발생할 수 있습니다. 이러한 문제를 방지하려면 System.Diagnostics.Debug.Assert 문에 함수 호출을 배치하는 대신 다음과 같이 임시 변수를 사용합니다.

temp = meas( i )
Debug.Assert (temp <> 0)
temp = meas( i );
Debug.Assert ( temp != 0 );

System.Diagnostics.Trace.Assert를 사용하는 경우에도 Assert 문 내에 함수 호출을 배치하지 않으려고 할 수 있습니다. System.Diagnostics.Trace.Assert 문은 릴리스 빌드에서 제거되지 않기 때문에 이러한 호출이 위험하지는 않습니다. 그러나 습관적으로 이러한 구문을 사용하지 않는 경우 System.Diagnostics.Debug.Assert를 사용할 때 실수를 줄일 수 있습니다.

항목 내용

Trace 및 Debug 요구 사항

Visual Studio 마법사를 사용하여 프로젝트를 만드는 경우 릴리스 구성과 디버그 구성 모두에서 기본적으로 TRACE 기호가 정의됩니다. 디버그 기호는 기본적으로 디버그 빌드에서만 정의됩니다.

그 밖의 경우에 Trace 메서드가 작동하려면 프로그램의 소스 파일 맨 위에 다음 중 하나가 있어야 합니다.

  • Visual Basic에서는 #Const TRACE = True

  • Visual C# 및 C++에서는 #define TRACE

    또는 다음과 같은 TRACE 옵션을 사용하여 프로그램을 빌드해야 합니다.

  • Visual Basic에서는 /d:TRACE=True

  • Visual C# 및 C++에서는 /d:TRACE

    C# 또는 Visual Basic 릴리스 빌드에서 Debug 메서드를 사용해야 하는 경우 릴리스 구성에서 디버그 기호를 정의해야 합니다.

    C++는 Debug 클래스 메서드를 지원하지 않습니다. 조건부 컴파일(예: #ifdef DEBUG... #endif)에 Trace 클래스를 사용하면 동일한 결과를 얻을 수 있습니다. 이러한 기호는 <Project> 속성 페이지 대화 상자에서 정의할 수 있습니다. 자세한 내용은 Visual Basic 디버그 구성에 대한 프로젝트 설정 변경 또는 C 또는 C++ 디버그 구성에 대한 프로젝트 설정 변경을 참조하세요.

어설션 인수

System.Diagnostics.Trace.AssertSystem.Diagnostics.Debug.Assert에는 세 가지 인수가 사용됩니다. 첫 번째 인수는 확인할 조건으로, 필수 인수입니다. 인수를 하나만 지정하여 System.Diagnostics.Trace.Assert(Boolean) 또는 System.Diagnostics.Debug.Assert(Boolean)를 호출하는 경우 Assert 메서드는 조건을 확인하여 결과가 false인 경우에 호출 스택의 내용을 출력 창에 출력합니다. 다음 예제에서는 System.Diagnostics.Trace.Assert(Boolean)System.Diagnostics.Debug.Assert(Boolean)를 보여 줍니다.

Debug.Assert(stacksize > 0)
Trace.Assert(stacksize > 0)
Debug.Assert ( stacksize > 0 );
Trace.Assert ( stacksize > 0 );

두 번째 및 세 번째 인수는 선택적으로 지정되는 문자열입니다. 인수를 두 개나 세 개 사용하여 System.Diagnostics.Trace.Assert 또는 System.Diagnostics.Debug.Assert를 호출하는 경우 첫 번째 인수는 조건입니다. 메서드는 조건을 확인하고 그 결과가 false인 경우 두 번째 문자열과 세 번째 문자열을 출력합니다. 다음 예제에서는 인수 두 개를 사용하는 System.Diagnostics.Debug.Assert(Boolean, String)System.Diagnostics.Trace.Assert(Boolean, String)를 보여 줍니다.

Debug.Assert(stacksize > 0, "Out of stack space")
Trace.Assert(stacksize > 0, "Out of stack space")
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );

다음 예제에서는 인수 세 개를 사용하는 System.Diagnostics.Debug.Assert(Boolean, String, String)System.Diagnostics.Trace.Assert(Boolean, String, String)를 보여줍니다.

Debug.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:", "inctemp failed on third call" )
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );

항목 내용

어설션 동작 사용자 지정

사용자 인터페이스 모드로 애플리케이션을 실행하는 경우 조건이 실패하면 Assert 메서드에서 어설션 실패 대화 상자를 표시합니다. 어설션이 실패할 경우에 발생하는 동작은 Listeners 또는 Listeners 속성으로 제어됩니다.

TraceListener 개체를 Listeners 컬렉션에 추가하거나, TraceListenerListeners 컬렉션에서 제거하거나, 기존 System.Diagnostics.TraceListener.FailTraceListener 메서드를 다르게 동작하도록 재정의하는 방법으로 출력 동작을 사용자 지정할 수 있습니다.

예를 들어 어설션 실패 대화 상자를 표시하는 대신 이벤트 로그에 쓰도록 System.Diagnostics.TraceListener.Fail 메서드를 재정의할 수 있습니다.

이러한 방법으로 출력을 사용자 지정하려면 프로그램에 수신기가 있어야 하고 사용자가 TraceListener에서 상속하여 System.Diagnostics.TraceListener.Fail 메서드를 재정의해야 합니다.

자세한 내용은 추적 수신기를 참조하세요.

항목 내용

구성 파일에서 어설션 설정

코드뿐만 아니라 프로그램 구성 파일에서도 어설션을 설정할 수 있습니다. 자세한 내용은 System.Diagnostics.Trace.Assert 또는 System.Diagnostics.Debug.Assert를 참조하세요.

참조