관리 코드에 어설션 사용
업데이트: 2007년 11월
이 항목은 다음 언어에 적용됩니다.
Edition |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Express |
||||
Standard |
||||
Pro 및 Team |
표의 범례:
해당 |
|
해당 없음 |
|
명령은 기본적으로 숨겨져 있습니다. |
어설션 즉 Assert 문은 Assert 문에 인수로 지정하는 조건을 검사합니다. 조건이 true로 평가되면 아무런 동작도 일어나지 않습니다. 조건이 false로 평가되면 어설션은 실패하게 됩니다. 디버그 빌드에서 실행 중인 경우 프로그램은 중단 모드를 시작합니다.
Visual Basic 및 Visual C#에서는 System.Diagnostics 네임스페이스에 있는 Debug 또는 Trace의 Assert 메서드를 사용할 수 있습니다. Debug 클래스 메서드는 릴리스 버전의 프로그램에 포함되지 않으므로 이 메서드를 사용해도 릴리스 코드의 크기가 증가하거나 속도가 느려지지 않습니다.
C++는 Debug 클래스 메서드를 지원하지 않습니다. #ifdef DEBUG... #endif 같은 조건부 컴파일에 Trace 클래스를 사용하면 동일한 결과를 얻을 수 있습니다.
Debug.Assert 메서드
코드가 정확한 경우 true로 유지되어야 하는 조건을 테스트하려면 Debug.Assert 메서드를 사용합니다. 예를 들어, 정수 divide 함수를 작성했다고 가정합시다. 수학의 규칙에 따라 0으로는 나눌 수 없습니다. 다음과 같이 어설션을 사용하여 이것을 테스트할 수 있습니다.
[Visual Basic]
Function IntegerDivide(ByVal dividend As Integer, ByVal divisor As Integer) As Integer
Debug.Assert(divisor <> 0)
Return CInt(dividend / divisor)
End Function
[C#]
int IntegerDivide ( int dividend , int divisor )
{ Debug.Assert ( divisor != 0 );
return ( dividend / divisor ); }
디버거에서 이 코드를 실행하면 어설션 문이 평가되지만, 릴리스 버전에서는 비교가 실행되지 않으므로 추가 오버헤드가 없습니다.
또는 다음과 같은 예를 들 수도 있습니다. 다음과 같이 당좌 예금 계좌를 구현하는 클래스가 있다고 가정합니다.
[Visual Basic]
Dim amount, balance As Double
balance = savingsAccount.balance
Debug.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
[C#]
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
계좌에서 돈을 인출하기 전에 인출하려는 금액 이상의 잔액이 있는지 확인해야 합니다. 다음과 같은 어설션으로 잔액을 확인할 수 있습니다.
[Visual Basic]
Dim amount, balance As Double
balance = savingsAccount.balance
Trace.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
[C#]
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
작성한 코드로 릴리스 버전을 만들면 Debug.Assert 메서드에 대한 호출이 없어집니다. 즉, 릴리스 버전에서는 잔액을 확인하는 호출이 없어집니다. 이 문제를 해결하려면 Debug.Assert 대신 릴리스 버전에서도 사라지지 않는 Trace.Assert를 사용해야 합니다.
Debug.Assert에 대한 호출과 달리 Trace.Assert에 대한 호출은 릴리스 버전에 오버헤드를 추가합니다.
Debug.Assert의 파생 작업
Debug.Assert를 사용할 때는 Assert가 제거되어도 Assert 내의 코드에 의해 프로그램의 결과가 변경되지 않도록 해야 합니다. 프로그램 결과가 변경되면 릴리스 버전 프로그램에만 나타나는 버그가 발생할 수 있습니다. 특히 다음 예와 같이 함수나 프로시저 호출이 포함된 Assert를 사용할 경우에 주의해야 합니다.
[Visual Basic]
' unsafe code
Debug.Assert (meas(i) <> 0 )
[C#]
// unsafe code
Debug.Assert (meas(i) != 0 );
위의 Debug.Assert가 안전해 보일 수도 있지만 meas 함수가 호출될 때마다 카운터를 업데이트한다고 가정해 보십시오. 릴리스 버전을 빌드할 때 이 meas에 대한 호출이 제거되므로 카운터는 업데이트되지 않습니다. 이것은 다른 작업이 포함된 함수의 예입니다. 다른 작업이 포함된 함수에 대한 호출을 제거하면 릴리스 버전에서만 나타나는 버그가 발생할 수 있습니다. 이러한 문제를 해결하려면 Debug.Assert 문에 함수 호출을 사용하는 대신 다음과 같이 임시 변수를 사용하십시오.
[Visual Basic]
temp = meas( i )
Debug.Assert (temp <> 0)
[C#]
temp = meas( i );
Debug.Assert ( temp != 0 );
Trace.Assert를 사용하는 경우에도 Assert 문 내에 함수 호출을 넣지 않는 것이 좋습니다. Trace.Assert 문은 릴리스 빌드에서 제거되지 않기 때문에 이러한 호출이 위험하지는 않습니다. 그러나 습관적으로 이러한 호출 구문을 사용하지 않으면 Debug.Assert를 사용할 때 실수를 줄일 수 있습니다.
Trace 및 Debug 요구 사항
Visual Studio 마법사를 사용하여 프로젝트를 만들면 Release 구성과 Debug 구성 모두에 기본적으로 TRACE 기호가 정의됩니다. DEBUG 기호는 기본적으로 디버그 빌드에서만 정의됩니다.
Trace 메서드가 제대로 작동하려면 프로그램의 소스 파일 맨 위에 다음 옵션 중 하나가 있어야 합니다.
#Const TRACE = True(Visual Basic의 경우)
#define TRACE(Visual C# 및 C++의 경우)
또는 TRACE 옵션을 사용하여 프로그램을 빌드해야 합니다.
/d:TRACE=True(Visual Basic의 경우)
/d:TRACE(Visual C# 및 C++의 경우)
C# 또는 Visual Basic 릴리스 빌드에서 Debug 메서드를 사용하려면 Release 구성에 DEBUG 기호를 정의해야 합니다.
C++는 Debug 클래스 메서드를 지원하지 않습니다. #ifdef DEBUG... #endif 같은 조건부 컴파일에 Trace 클래스를 사용하면 동일한 결과를 얻을 수 있습니다. 이 기호는 <Project> 속성 페이지 대화 상자에서 정의할 수 있습니다. 자세한 내용은 Visual Basic 디버그 구성에 대한 프로젝트 설정 변경 또는 C 또는 C++ 디버그 구성에 대한 프로젝트 설정 변경을 참조하십시오.
Assert 인수
Trace.Assert 및 Debug.Assert에는 세 가지 인수가 사용됩니다. 첫 번째 인수는 검사할 조건으로, 필수 인수입니다. 인수를 하나만 지정하여 Trace.Assert(Boolean) 또는 Debug.Assert(Boolean)를 호출하면 Assert 메서드는 조건을 검사하여 결과가 false인 경우에 호출 스택의 내용을 출력 창에 표시합니다. 다음 예제에서는 Trace.Assert(Boolean) 및 Debug.Assert(Boolean)를 보여 줍니다.
[Visual Basic]
Debug.Assert(stacksize > 0)
Trace.Assert(stacksize > 0)
[C#]
Debug.Assert ( stacksize > 0 );
Trace.Assert ( stacksize > 0 );
두 번째와 세 번째 인수는 선택적으로 지정되는 문자열입니다. 두 개 또는 세 개의 인수를 사용하여 Trace.Assert 또는 Debug.Assert를 호출하는 경우 첫 번째 인수는 조건입니다. 메서드는 조건을 검사하고 그 결과가 false인 경우 두 번째 문자열과 세 번째 문자열을 출력합니다. 다음 예제에서는 인수 두 개를 사용하는 Debug.Assert(Boolean, String) 및 Trace.Assert(Boolean, String)를 보여 줍니다.
[Visual Basic]
Debug.Assert(stacksize > 0, "Out of stack space")
Trace.Assert(stacksize > 0, "Out of stack space")
[C#]
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );
다음 예제에서는 Assert 및 Assert를 보여 줍니다.
[Visual Basic]
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" )
[C#]
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );
Assert 동작 사용자 지정
사용자 인터페이스 모드로 응용 프로그램을 실행하는 경우 조건이 실패하면 Assert 메서드에서 어설션 오류 대화 상자를 표시합니다. 어설션이 실패할 경우에 발생하는 동작은 Listeners 또는 Listeners 속성에 의해 제어됩니다.
TraceListener 개체를 Listeners 컬렉션에 추가하거나, TraceListener를 Listeners 컬렉션에서 제거하거나, 기존 TraceListener의 TraceListener.Fail 메서드를 다르게 동작하도록 재정의하는 방법으로 출력 동작을 사용자 지정할 수 있습니다.
예를 들어, 어설션 오류 대화 상자를 표시하는 대신 이벤트 로그에 쓰도록 TraceListener.Fail 메서드를 재정의할 수 있습니다.
이러한 방법으로 출력을 사용자 지정하려면 프로그램에 수신기가 있어야 하고 사용자가 TraceListener에서 상속하여 TraceListener.Fail 메서드를 재정의해야 합니다.
자세한 내용은 추적 수신기를 참조하십시오.
구성 파일에 어설션 설정
코드뿐만 아니라 프로그램 구성 파일에도 어셜선을 설정할 수 있습니다. 자세한 내용은 Trace.Assert 또는 Debug.Assert를 참조하십시오.