CS 전문가로 졸업 한 후 약 1 년 동안 전문 소프트웨어 엔지니어로 일했습니다. 나는 C ++과 C에서 한동안 주장에 대해 알고 있었지만 최근까지 C #과 .NET에 존재한다는 것을 전혀 몰랐다.
우리의 생산 코드에는 어떤 주장도 포함되어 있지 않으며 내 질문은 이것입니다 …
프로덕션 코드에서 Asserts를 사용해야합니까? 그렇다면 언제 사용하는 것이 가장 적합합니까? 하는 것이 더 합리적일까요?
Debug.Assert(val != null);
또는
if ( val == null )
throw new exception();
답변
에서 디버깅 마이크로 소프트 .NET 2.0 응용 프로그램 존 로빈스의 주장에 큰 부분을 가지고있다. 그의 요점은 다음과 같습니다.
- 자유롭게 주장하십시오. 너무 많은 어설 션을 가질 수 없습니다.
- 어설 션은 예외를 대체하지 않습니다. 코드에서 요구하는 사항은 예외입니다. 주장은 가정하는 것을 포함합니다.
- 잘 작성된 어설 션은 무슨 일이 있었는지와 예외 (예 : 예외)뿐만 아니라 그 이유를 알려줄 수 있습니다.
- 예외 메시지는 종종 암호가 될 수 있으므로 오류를 일으킨 컨텍스트를 다시 작성하기 위해 코드를 거꾸로 작업해야합니다. 어설 션은 오류가 발생한 시점의 프로그램 상태를 보존 할 수 있습니다.
- 어설 션은 문서로 두 배가되어 다른 개발자에게 코드가 의존하는 가정을 알려줍니다.
- 어설 션이 실패 할 때 나타나는 대화 상자를 사용하면 프로세스에 디버거를 연결할 수 있으므로 중단 점을 배치 한 것처럼 스택 주위를 찌를 수 있습니다.
추신 : Code Complete가 마음에 드 셨다면이 책을 참조하십시오. WinDBG 및 덤프 파일 사용에 대해 배우기 위해 구입했지만 전반부는 처음에 버그를 피하는 데 도움이되는 팁으로 가득합니다.
답변
Debug.Assert()
불변성을 보장하기 위해 위생 검사를 원하는 코드의 모든 곳에 넣습니다 . 릴리스 빌드를 컴파일 할 때 (즉, DEBUG
컴파일러 상수 없음 ) 호출 Debug.Assert()
은 제거되어 성능에 영향을 미치지 않습니다.
를 호출하기 전에 여전히 예외를 처리해야합니다 Debug.Assert()
. 어설 션은 개발하는 동안 모든 것이 예상대로 이루어 지도록합니다.
답변
에서 코드 완성
8 방어 프로그래밍
8.2 주장
어설 션은 개발 중에 사용되는 코드 (일반적으로 루틴 또는 매크로)로 프로그램이 실행될 때 자체적으로 확인할 수 있습니다. 어설 션이 true이면 모든 것이 예상대로 작동한다는 의미입니다. False이면 코드에서 예기치 않은 오류가 감지되었음을 의미합니다. 예를 들어, 시스템에서 고객 정보 파일에 레코드가 50,000 개를 넘지 않는다고 가정하면 프로그램에 레코드 수가 50,000보다 작거나 같다는 주장이 프로그램에 포함될 수 있습니다. 레코드 수가 50,000보다 작거나 같은 한 어설 션은 자동입니다. 그러나 50,000 개가 넘는 레코드가 발견되면 프로그램에 오류가 있다고 크게 “어설트”합니다.
어설 션은 특히 크고 복잡한 프로그램과 높은 안정성의 프로그램에서 유용합니다. 이를 통해 프로그래머는 불일치 한 인터페이스 가정, 코드 수정시 발생하는 오류 등을보다 신속하게 제거 할 수 있습니다.
어설 션은 일반적으로 두 가지 인수, 즉 참이라고 가정하는 가정을 설명하는 부울 식과 그렇지 않은 경우 표시 할 메시지를받습니다.
(…)
일반적으로 사용자는 프로덕션 코드에서 어설 션 메시지를 보지 않기를 원합니다. 어설 션은 주로 개발 및 유지 관리 중에 사용됩니다. 어설 션은 일반적으로 개발시 코드로 컴파일되고 프로덕션 코드에서 컴파일됩니다. 개발 중에 어설 션은 모순 된 가정, 예기치 않은 조건, 잘못된 값이 루틴에 전달되는 등을 제거합니다. 생산하는 동안 어설 션이 시스템 성능을 저하시키지 않도록 코드에서 컴파일됩니다.
답변
FWIW … 공개 메소드가 if () { throw; }
패턴을 사용하여 메소드가 올바르게 호출되도록하는 경향이 있습니다 . 내 개인적인 방법은 사용하는 경향이 있습니다Debug.Assert()
.
아이디어는 내 개인 메서드를 사용하여 제어하는 방법이므로 잘못된 매개 변수로 자체 개인 메서드 중 하나를 호출하기 시작하면 어딘가에서 내 자신의 가정을 어겼습니다. 그 상태로. 프로덕션 환경에서 이러한 개인 주장은 내부 상태를 유효하고 일관되게 유지해야하므로 이상적으로 불필요한 작업이어야합니다. 런타임에 누구나 호출 할 수있는 공용 메소드에 제공된 매개 변수와 대조 : 여전히 예외를 발생시켜 매개 변수 제약 조건을 적용해야합니다.
또한 런타임에 무언가 작동하지 않는 경우 (네트워크 오류, 데이터 액세스 오류, 타사 서비스에서 검색 한 잘못된 데이터 등) 내 개인 메서드는 여전히 예외를 throw 할 수 있습니다. 내 주장은 그 물체의 상태에 대한 내 자신의 가정을 깨뜨리지 않도록하기 위해 거기에 있습니다.
답변
어설 션을 사용하여 개발자 가정을 확인하고 예외를 환경 가정을 확인하십시오.
답변
내가 당신이라면 내가 할 것입니다 :
Debug.Assert(val != null);
if ( val == null )
throw new exception();
또는 반복적 인 상태 점검을 피하기 위해
if ( val == null )
{
Debug.Assert(false,"breakpoint if val== null");
throw new exception();
}
답변
프로덕션 코드 (예 : 릴리스 빌드)에 Asserts를 원하는 경우 Debug.Assert 대신 Trace.Assert를 사용할 수 있습니다.
이것은 물론 프로덕션 실행 파일에 오버 헤드를 추가합니다.
또한 응용 프로그램이 사용자 인터페이스 모드에서 실행중인 경우 어설 션 대화 상자가 기본적으로 표시되어 사용자에게 약간의 혼란을 줄 수 있습니다.
DefaultTraceListener를 제거하여이 동작을 무시할 수 있습니다. MSDN의 Trace.Listeners 설명서를 참조하십시오.
요약해서 말하자면,
-
Debug.Assert를 자유롭게 사용하여 디버그 빌드에서 버그를 잡을 수 있습니다.
-
사용자 인터페이스 모드에서 Trace.Assert를 사용하는 경우 사용자가 당황하지 않도록 DefaultTraceListener를 제거 할 수 있습니다.
-
테스트중인 조건이 앱이 처리 할 수없는 조건 인 경우 예외가 발생하여 실행이 계속되지 않도록하는 것이 좋습니다. 사용자는 어설 션을 무시하도록 선택할 수 있습니다.