문제

나는 전문 소프트웨어 엔지니어에 대한 지금으로 의과 대학을 졸업하고 lg 정도입니다.나는에 대해 알려진 주장에 대해안에서는 C++과 C 지만,아무 생각이 없었에 존재했 C#다.순서 모든 최근까지.

우리의 생산 코드가 포함되어 있지 않고 주장한 어떠한 제 질문은 이...

시간 사용하는 주장에 우리의 생산 코드?그렇다면을 때,그것의 사용은 가장 적절한가?그것은 더 이해하지

Debug.Assert(val != null);

if ( val == null )
    throw new exception();
도움이 되었습니까?

해결책

디버깅 Microsoft.NET2.0 응용 프로그램 존 로빈스는 섹션에서 주장.그의 주요 포인트:

  1. Assert 자유롭게.할 수 있는 결코 너무 많은 assertions.
  2. Assertions 를 대체하지 않는 예외가 있습니다.예외를 덮는 것이 당신의 코드를 요구;션을 덮는 것으로 가정.
  3. 잘 쓴 주장 당신에게 말할 수 있지만 어떤 일이 일어났고는(좋아하는 예외),그런데 왜.
  4. 예외 메시지가 표시될 수 있한 요구,당신을 거꾸로 작동 코드를 통해 재현하는 상황 발생에 오류가 있습니다.는 주장이 유지 할 수 있는 프로그램의 국가에서 시간의 오류가 발생했습니다.
  5. 단 두 번으로 문서를 말하고,다른 개발자들이 무엇을 암시하는 가정의 코드에 따라 달라집니다.
  6. 대화할 때 나타나는 주장이 실패할 수 있 디버거를 연결하는 과정,그래서 당신은 당신을 찌를 수 있습니다 주위 스택으로 당신을 중단점이 있다.

PS:만약 당신이 좋아하는 코드가 완료되면,추천이 다음 그것은 이 책이다.나는 그것을 샀을 사용하는 방법에 대한 자세한 내용은 WinDBG 덤프파일,그러나 상반기에 포상을 방지하는 데 도움이 버그에서 첫 번째 장소입니다.

다른 팁

을 넣 Debug.Assert() 방 코드에서는 당신이 원하는 정신이 있는지 확인합니 invariants.를 컴파일할 때 해제 구축(즉, DEBUG 컴파일러에 일정한다),전화 Debug.Assert() 제거됩니다 그래서 그들은하지 않습니다 성능에 영향을 미칩니다.

당신은 여전히 던져 예외를 호출하기 전에 Debug.Assert().Assert 단지 확인하는 것으로 예상되는 동안 당신은 여전히 개발하고 있습니다.

에서 코드 완료

8 방어 프로그래밍

8.2 주장

주장은 개발 중에 사용되는 코드 (일반적으로 일상 또는 매크로)로서 프로그램이 실행될 때 자체적으로 확인할 수 있도록합니다. 주장이 사실 일 때, 그것은 모든 것이 예상대로 작동한다는 것을 의미합니다. 거짓 인 경우 코드에서 예상치 못한 오류를 감지했음을 의미합니다. 예를 들어, 시스템이 고객 정보 파일에 50,000 개를 넘지 않는다고 가정하면 프로그램에 레코드 수가 적거나 50,000에 해당한다는 주장이 포함될 수 있습니다. 레코드 수가 50,000보다 작거나 동일하다면, 그 주장은 침묵 할 것입니다. 그러나 5 만 개가 넘는 레코드가 발생하면 프로그램에 오류가 있다고 큰 소리로 "주장"합니다.

주장은 특히 대규모 복잡한 프로그램과 높은 신뢰성 프로그램에서 유용합니다. 프로그래머는 불일치 한 인터페이스 가정, 코드가 수정 될 때 발생하는 오류 등을보다 빠르게 플러시 할 수있게합니다.

주장은 일반적으로 두 가지 주장을 취합니다 : 사실로 여겨지는 가정을 설명하는 부울 표현과 그렇지 않은 경우 표시되는 메시지.

(…)

일반적으로 사용자는 프로덕션 코드에서 어설 션 메시지를보고 싶지 않습니다. 주장은 주로 개발 및 유지 보수 중에 사용하기위한 것입니다. 어설 션은 일반적으로 개발 시간에 코드로 컴파일되며 프로덕션 코드에서 컴파일됩니다. 개발 중에 어설 션은 모순 된 가정, 예상치 못한 조건, 나쁜 값이 루틴으로 전달되는 등을 씻어냅니다. 생산 중에는 주장이 시스템 성능을 저하시키지 않도록 코드에서 컴파일됩니다.

fwiw ... 내 공개 방법이 if () { throw; } 메소드가 올바르게 호출되는지 확인하는 패턴. 내 개인 방법은 사용하는 경향이 있습니다 Debug.Assert().

아이디어는 내 개인 방법으로, 나는 통제력이있는 사람이므로, 부정확 한 매개 변수로 내 개인 방법 중 하나를 호출하기 시작하면 어딘가에 내 자신의 가정을 깨뜨 렸습니다. 그 상태로. 제작에서 이러한 개인 주장은 내부 상태를 유효하고 일관성있게 유지해야하기 때문에 이상적으로 불필요한 작업이어야합니다. 런타임에서 누구나 호출 할 수있는 공개 메소드에 주어진 매개 변수와 대조적입니다. 예외를 던져서 매개 변수 제약 조건을 시행해야합니다.

또한 런타임 (네트워크 오류, 데이터 액세스 오류, 타사 서비스에서 검색된 잘못된 데이터 등)에서 작동하지 않으면 개인 메소드가 여전히 예외를 제외 할 수 있습니다. 내 주장은 내가 물체의 상태에 대한 내 내부 가정을 깨뜨리지 않았는지 확인하기 위해 거기에 있습니다.

Asserts를 사용하여 개발자 가정 및 예외를 확인하여 환경 가정을 확인하십시오.

내가 당신이라면 나는 할 것입니다 :

Debug.Assert(val != null);
if ( val == null )
    throw new exception();

또는 반복적 인 상태 점검을 피하기 위해

if ( val == null )
{
    Debug.Assert(false,"breakpoint if val== null");
    throw new exception();
}

프로덕션 코드 (예 : 릴리스 빌드)에서 어서를 원한다면 Debug.Assert 대신 Trace.Assert를 사용할 수 있습니다.

물론 이것은 생산 실행 파일에 오버 헤드를 추가합니다.

또한 응용 프로그램이 사용자 인터페이스 모드로 실행중인 경우 기본적으로 어설 션 대화 상자가 표시되며 사용자에게 약간 당황 할 수 있습니다.

DefaultTracelistener를 제거 하여이 동작을 무시할 수 있습니다. MSDN의 Trace.Listeners에 대한 문서를보십시오.

요약해서 말하자면,

  • 디버그 빌드에서 버그를 잡는 데 도움이되도록 Debug.Assert를 사용하여 사용하십시오.

  • 사용자 인터페이스 모드에서 trace.Assert를 사용하는 경우 DEFAULTTRACELISTERE를 제거하여 당황스러운 사용자를 피할 수 있습니다.

  • 테스트하는 조건이 앱을 처리 할 수없는 것이라면 실행이 계속되지 않도록 예외를 던지는 것이 좋습니다. 사용자는 주장을 무시하도록 선택할 수 있습니다.

Asserts는 사용자 오류가 아닌 프로그래머 (귀하의) 오류를 포착하는 데 사용됩니다. 사용자가 어설 션을 발사 할 가능성이없는 경우에만 사용해야합니다. 예를 들어 API를 작성하는 경우 API 사용자가 호출 할 수있는 방법에서 인수가 무효가 아닌지 확인하는 데 사용되지 않아야합니다. 그러나 API의 일부로 노출되지 않은 개인 방법으로 사용하여 코드가 예상되지 않을 때는 널 인수를 전달하지 않는다고 주장합니다.

나는 보통 내가 확실하지 않을 때 Asserts보다 예외를 선호합니다.

대부분 내 책에는 결코 없습니다. 모든 것이 제정신인지 확인하고 싶다면 대부분의 경우에는 그렇지 않은 경우 던지십시오.

내가 싫어하는 것은 디버그 빌드가 릴리스 빌드와 기능적으로 다르다는 사실입니다. 디버그 어제가 실패하지만 기능이 릴리스에서 작동하면 어떻게 이해가됩니까? 어서터가 오랫동안 회사를 떠났고 코드의 일부를 모르는 사람은 아무도 모른다는 것이 더 좋습니다. 그런 다음 문제가 실제로 문제인지 아닌지 확인하기 위해 시간을 죽여야합니다. 문제라면 왜 사람이 처음에 던지지 않습니까?

나에게 이것은 Debug.Asserts를 사용하여 다른 사람에게 문제를 연기하고 문제를 직접 처리합니다. 무언가가 사실이되어야하고 그것은 던지지 않습니다.

어설 션을 최적화하려는 성능 중요한 시나리오가있을 수 있으며 유용하지만 아직 그러한 시나리오를 만나지 못했습니다.

요컨대

Asserts 경비원 및 계약 제약으로 설계 확인에 사용됩니다.

  • Asserts 디버그 및 비 생산 빌드만을위한 것입니다. 릴리스 빌드에서 컴파일러에 의해 일반적으로 어서 대계합니다.
  • Asserts 시스템 제어에있는 버그 / 예기치 않은 조건을 확인할 수 있습니다.
  • Asserts 사용자 입력 또는 비즈니스 규칙의 일차 검증 메커니즘이 아닙니다.
  • Asserts ~해야 한다 ~ 아니다 예기치 않은 환경 조건 (코드 제어를 벗어난)을 감지하는 데 사용됩니다 (예 : 메모리, 네트워크 고장, 데이터베이스 고장 등)는 드물지만 이러한 조건은 예상되어야합니다 (및 앱 코드는 하드웨어 고장과 같은 문제를 해결할 수 없습니다. 또는 자원 소진). 일반적으로 예외가 발생합니다. 응용 프로그램은 수정 조치 (예 : 데이터베이스 또는 네트워크 작업을 재 시도하거나 캐시 된 메모리를 확보하려고 시도) 또는 예외를 처리 할 수없는 경우 우아하게 중단 할 수 있습니다.
  • 실패한 주장은 시스템에 치명적이어야합니다. 즉, 예외와 달리, 시도하고 잡기 또는 처리하지 마십시오. Asserts - 코드는 예상치 못한 영역에서 운영됩니다. 스택 추적 및 충돌 덤프를 사용하여 무엇이 잘못되었는지 결정할 수 있습니다.

주장에는 엄청난 이점이 있습니다.

  • 높은 레벨 코드에서 사용자 입력 유효성 검증 또는 업스트림 버그가 누락 된 것을 찾는 데 도움이됩니다.
  • 코드 기반의 주장은 코드의 가정을 독자에게 명확하게 전달합니다.
  • Assert는 런타임에 확인됩니다 Debug 빌드.
  • 코드가 철저하게 테스트되면 릴리스로 코드를 재건하면 가정을 확인하는 성능 오버 헤드가 제거됩니다 (그러나 나중에 디버그 빌드가 항상 수표를 되돌릴 수 있습니다.

... 자세한 세부 사항

Debug.Assert 프로그램 제어 내에서 코드 블록의 나머지 부분에 의해 상태에 대해 가정 된 조건을 표현합니다. 여기에는 제공된 매개 변수의 상태, 클래스 인스턴스의 구성원 상태 또는 메소드 호출에서의 수익이 계약 / 설계 범위에 있음이 포함될 수 있습니다. 일반적으로 Asserts는 필요한 모든 정보 (스택 추적, 충돌 덤프 등)와 함께 스레드 / 프로세스 / 프로그램에 충돌해야합니다. (즉, 설계되지 않은 버그 또는 소반 조건이 있음을 나타냅니다. 어설 션 실패 핸들), 어설 션 자체가 버그보다 더 많은 손상을 일으킬 수있는 경우를 제외하고 한 가지 가능한 한 가지가 있습니다 (예 : 항공 교통 관제사는 항공기가 잠수함이있을 때 YSOD를 원하지 않을 것입니다. 생산 ...)

언제 사용해야합니까? Asserts?- 시스템 또는 라이브러리 API 또는 클래스의 함수 또는 상태에 대한 입력이 유효한 것으로 가정되는 서비스의 어느 시점에서 (예 : 시스템, 비즈니스 및 시스템의 프리젠 테이션 계층에서 사용자 입력에 대한 유효성 검사가 완료된 경우 데이터 계층 클래스는 일반적으로 널 확인, 범위 검사, 문자열 길이 검사 등이 이미 완료되었다고 가정합니다). - 흔한 Assert 검사에는 잘못된 가정이 무효 객체 피로, 제로 디바이저, 숫자 또는 날짜 산술 오버 플로우, 그리고 행동을 위해 설계되지 않은 밴드의 일반적인 / 밴드에서 일반적인 객체를 모델링하는 데 사용되는 경우 (예 : 32 비트 int가 인간의 나이를 모델링하는 경우, IT)가 포함됩니다. 신중 할 것입니다 Assert 나이는 실제로 0에서 125 정도 사이입니다 - -100과 10^10의 값은 설계되지 않았습니다).

.NET 코드 계약
.NET 스택에서 코드 계약 사용할 수 있습니다 외에 또는 대안으로 사용 Debug.Assert. 코드 계약은 주 검진을 더 공식화 할 수 있으며, ~ 컴파일 시간 (또는 그 후 곧 IDE에서 배경 점검으로 실행되는 경우)에서 가정 위반을 감지하는 데 도움이 될 수 있습니다.

계약 별 설계 (DBC) 수표에는 다음이 포함됩니다.

  • Contract.Requires - 수축 전제 조건
  • Contract.Ensures - 계약 후 전투
  • Invariant - 수명의 모든 지점에서 물체의 상태에 대한 가정을 표현합니다.
  • Contract.Assumes - 비 계약 장식 방법을 호출 할 때 정적 검사기를 진정시킵니다.

에 따르면 IdeSign 표준, 당신은해야합니다

모든 가정을 주장합니다. 평균적으로, 모든 다섯 번째 라인은 주장입니다.

using System.Diagnostics;

object GetObject()
{...}

object someObject = GetObject();
Debug.Assert(someObject != null);

면책 조항으로서 나는이 IRL을 구현하는 것이 실용적이지 않다는 것을 언급해야합니다. 그러나 이것은 그들의 표준입니다.

릴리스 빌드를 위해 수표를 제거하려는 경우에만 어설 션을 사용하십시오. 디버그 모드에서 컴파일하지 않으면 어설 션이 발사되지 않습니다.

널 검사 예를 감안할 때, 이것이 내부 전용 API에 있으면 어설 션을 사용할 수 있습니다. 그것이 공개 API에 있다면, 나는 명백한 점검과 던지기를 분명히 사용합니다.

모든 주장은 다음과 같은 최적화 할 수있는 코드 여야합니다.

Debug.Assert(true);

이미 가정했던 것을 확인하는 것이 사실이기 때문입니다. 예 :

public static void ConsumeEnumeration<T>(this IEnumerable<T> source)
{
  if(source != null)
    using(var en = source.GetEnumerator())
      RunThroughEnumerator(en);
}
public static T GetFirstAndConsume<T>(this IEnumerable<T> source)
{
  if(source == null)
    throw new ArgumentNullException("source");
  using(var en = source.GetEnumerator())
  {
    if(!en.MoveNext())
      throw new InvalidOperationException("Empty sequence");
    T ret = en.Current;
    RunThroughEnumerator(en);
    return ret;
  }
}
private static void RunThroughEnumerator<T>(IEnumerator<T> en)
{
  Debug.Assert(en != null);
  while(en.MoveNext());
}

위에서는 Null 매개 변수에 대한 세 가지 다른 접근법이 있습니다. 첫 번째는 그것을 허용 가능한 것으로 받아들입니다 (아무것도하지 않습니다). 두 번째는 호출 코드가 처리 할 예외가 발생합니다 (또는 오류 메시지가 발생하지 않음). 세 번째는 그것이 일어날 수 없다고 가정하고 그것이 그렇게되었다고 주장합니다.

첫 번째 경우에는 아무런 문제가 없습니다.

두 번째 경우 호출 코드에 문제가 있습니다. GetFirstAndConsume null이 있으므로 예외가됩니다.

세 번째 경우,이 코드에는 이미 확인 되었기 때문에이 코드에 문제가 있습니다. en != null 그것이 부름을 받기 전에, 그것이 사실이 아니라는 것은 버그입니다. 즉, 이론적으로 최적화 될 수있는 코드 여야합니다. Debug.Assert(true), Sicne en != null 항상 있어야합니다 true!

Debug.Assert가 올바른 선택이 될 수있는 4 가지 사례를 더 추가 할 것이라고 생각했습니다.

1) 내가 여기서 언급하지 않은 것은 다음과 같습니다 자동 테스트 중에 추가 개념적 커버리지 어시스트가 제공 할 수 있습니다. 간단한 예로 :

추가 시나리오를 처리하기 위해 코드의 범위를 확장했다고 생각하는 일부 상위 수준의 발신자가 수정되면 이상적으로는이 새로운 조건을 다루기 위해 단위 테스트를 작성합니다. 그런 다음 완전히 통합 된 코드가 잘 작동하는 것처럼 보일 수 있습니다.

그러나 실제로 미묘한 결함이 도입되었지만 테스트 결과에서는 감지되지 않았습니다. 이 경우 Callee는 비 결정적이되었으며 발생합니다 예상 결과를 제공합니다. 또는 아마도 눈에 띄지 않은 반올림 오류가 발생했을 수도 있습니다. 또는 다른 곳에서 똑같이 오프셋 된 오류가 발생했습니다. 또는 요청 된 액세스뿐만 아니라 부여해서는 안되는 추가 권한을 부여했습니다. 등.

이 시점에서, 단위 테스트에 의해 구동되는 새로운 사례 (또는 에지 케이스)와 결합 된 Callee에 포함 된 Debug.assert () 문은 원래 작성자의 가정이 무효화되었음을 테스트 중에 귀중한 알림을 제공 할 수 있으며, 코드는 안정되지 않아야한다는 것을 테스트하는 동안 귀중한 알림을 제공 할 수 있습니다. 추가 검토없이 출시됩니다. 단위 테스트와 함께 주장하는 것이 완벽한 파트너입니다.

2) 또한, 일부 테스트는 쓰기가 간단하지만 초기 가정을 고려할 때 고비용 및 불필요합니다.. 예를 들어:

특정 보안 입력 지점에서 객체에 액세스 할 수있는 경우, 발신자가 권한을 갖도록 모든 객체 방법에서 네트워크 권한 데이터베이스에 추가 쿼리를 작성해야합니까? 분명히 아니다. 아마도 이상적인 솔루션에는 캐싱 또는 다른 기능 확장이 포함되지만 디자인에는 필요하지 않습니다. Debug.assert ()는 객체가 불안한 진입 점에 첨부되었을 때 즉시 표시됩니다.

3) 다음으로, 어떤 경우에는 제품은 릴리스 모드로 배포 될 때 작업의 전부 또는 일부에 도움이되는 진단 상호 작용이 없을 수 있습니다.. 예를 들어:

내장 실시간 장치라고 가정 해 봅시다. 예외를 던지고 기형 패킷이 발생할 때 다시 시작하는 것은 비생산적입니다. 대신이 장치는 출력의 노이즈를 렌더링하는 시점까지도 최상의 효과 작동으로 이점을 얻을 수 있습니다. 또한 릴리스 모드로 배포 될 때 휴먼 인터페이스, 로깅 장치가 없거나 인간이 물리적으로 액세스 할 수 없으며 동일한 출력을 평가하여 오류에 대한 인식이 가장 잘 제공됩니다. 이 경우, 자유주의 주장과 철저한 사전 방출 테스트는 예외보다 더 가치가 있습니다.

4) 마지막으로, 일부 테스트는 Callee가 극도로 신뢰할 수있는 것으로 인식되기 때문에 불필요합니다.. 대부분의 경우 재사용 가능한 코드가 더 많을수록 신뢰할 수 있도록 더 많은 노력을 기울였습니다. 따라서 발신자의 예상치 못한 매개 변수에 대해서는 예외적이지만 Callees의 예기치 않은 결과를 주장합니다. 예를 들어:

핵심 인 경우 String.Find 운영에 따르면 반환 할 수 있습니다 -1 검색 기준을 찾을 수없는 경우 3 개가 아닌 하나의 작업을 안전하게 수행 할 수 있습니다. 그러나 실제로 돌아온 경우 -2, 당신은 합리적인 행동 과정이 없을 수 있습니다. 더 간단한 계산을보다 따로 테스트하는 계산으로 대체하는 것은 도움이되지 않습니다. -1 대부분의 릴리스 환경에서 값과 비합리적이지 않으면 코드가 예상대로 작동하도록 테스트를 통해 코드를 쓰러 뜨립니다. 이 경우 어설 션은 이상적입니다.

인용문 실용적인 프로그래머 : Journeyman에서 마스터까지

어설 션을 켜십시오

컴파일러와 언어 환경을 작성하는 사람들에 의해 공표 된 주장에 대한 일반적인 오해가 있습니다. 그것은 다음과 같이 간다 :

어설 션 코드에 약간의 오버 헤드가 추가됩니다. 절대 일어나지 말아야 할 일이 있는지 확인하기 때문에 코드의 버그만으로 유발됩니다. 코드를 테스트하고 배송 한 후에는 더 이상 필요하지 않으며 코드를 더 빨리 실행하도록 꺼야합니다. 주장은 디버깅 시설입니다.

여기에는 특허 적으로 잘못된 가정이 있습니다. 먼저 테스트가 모든 버그를 찾는다고 가정합니다. 실제로 복잡한 프로그램의 경우 코드가 적용되는 순열의 미세한 비율조차 테스트하지는 않습니다 (무자비한 테스트 참조).

둘째, 낙관론자들은 당신의 프로그램이 위험한 세상에서 운영된다는 것을 잊고 있습니다. 테스트하는 동안 쥐는 통신 케이블을 gna 아 먹지 않을 것입니다. 게임을하는 사람이 메모리를 배출하지 않으며 로그 파일은 하드 드라이브를 채우지 않습니다. 이러한 일은 프로그램이 생산 환경에서 실행될 때 발생할 수 있습니다. 첫 번째 방어선은 가능한 오류를 확인하는 것이며, 두 번째는 주장을 사용하여 놓친 것들을 감지하는 것입니다.

프로덕션에 프로그램을 제공 할 때 어설 션을 끄는 것은 한 번 실제로 그것을 만들었 기 때문에 그물없이 하이 와이어를 건너는 것과 같습니다.. 극적인 가치는 있지만 생명 보험을 얻는 것은 어렵습니다.

성능 문제가 있더라도 실제로 당신을 때리는 주장 만 끄십시오..

항상 두 번째 접근법 (제외 예외)을 사용해야합니다.

또한 생산중인 경우 (그리고 릴리스 건물이있는 경우) 유효하지 않은 값으로 작업하고 고객의 데이터를 파괴하는 것보다 예외를 던지고 최악의 상황에서 충돌하는 것이 좋습니다 (수천 달러의 비용이 발생할 수 있습니다. 달러의).

Debug.Assert를 사용하여 프로그램의 논리적 오류를 테스트해야합니다. Complier는 구문 오류 만 알려줄 수 있습니다. 따라서 논리적 오류를 테스트하기 위해 Assert 진술을 분명히 사용해야합니다. 파란색 인 BMW 만 판매하는 자동차를 판매하는 프로그램을 테스트하는 것처럼 15% 할인을 받아야합니다. Complier는 귀하의 프로그램이이를 수행하는 데 논리적으로 올바른지에 대해 아무것도 말할 수 없지만 Assert 진술은 할 수 있습니다.

나는 여기서 답을 읽었고 중요한 차이점을 추가해야한다고 생각했습니다. 어셈블리가 사용되는 두 가지 매우 다른 방법이 있습니다. 하나는 프로그램이 계속 될 수있는 경우 조건부 중단 점과 같은 일종의 조건부 중단 점과 같은 일종의 "이런 일이 일어나지 않아야하므로 알 수 있도록 알 수 있도록 알 수 있도록"임시 개발자 바로 가기입니다. 다른 하나는 유효한 프로그램 상태에 대한 가정을 코드에 넣는 방법입니다.

첫 번째 경우, 어설 션은 최종 코드에있을 필요조차 없습니다. 당신은 사용해야합니다 Debug.Assert 개발 중에 더 이상 필요하지 않은 경우를 제거 할 수 있습니다. 당신이 그들을 떠나고 싶거나 제거하는 것을 잊어 버린 경우, 문제가 없다면 릴리스 편집에 아무런 영향을 미치지 않기 때문입니다.

그러나 두 번째 경우, 어설 션은 코드의 일부입니다. 그들은 당신의 가정이 사실이라고 주장하고 그것들을 문서화한다고 주장합니다. 이 경우 코드에 남겨두고 싶습니다. 프로그램이 유효하지 않은 상태 인 경우 계속해서는 안됩니다. 성능 히트를 감당할 수 없다면 C#을 사용하지 않을 것입니다. 한편으로는 디버거가 발생하면 디버거를 부착 할 수있는 것이 유용 할 수 있습니다. 다른 한편으로, 당신은 사용자에게 스택 추적이 나타나는 것을 원하지 않으며 아마도 더 중요 할 것입니다. 게다가, 서비스에 있다면 항상 무시됩니다. 따라서 제작에서 올바른 동작은 예외를 던지고 프로그램의 일반적인 예외 처리를 사용하는 것이며, 이는 사용자에게 좋은 메시지를 보여주고 세부 사항을 기록 할 수 있습니다.

Trace.Assert 이것을 달성하는 완벽한 방법이 있습니다. 생산에서 제거되지 않으며 App.Config를 사용하여 다른 리스너로 구성 할 수 있습니다. 따라서 개발을 위해서는 기본 핸들러가 적합하며 프로덕션의 경우 아래와 같은 간단한 TracElistener를 만들 수 있으며 예외가 발생하여 프로덕션 구성 파일에서 활성화 할 수 있습니다.

using System.Diagnostics;

public class ExceptionTraceListener : DefaultTraceListener
{
    [DebuggerStepThrough]
    public override void Fail(string message, string detailMessage)
    {
        throw new AssertException(message);
    }
}

public class AssertException : Exception
{
    public AssertException(string message) : base(message) { }
}

그리고 프로덕션 구성 파일에서 :

<system.diagnostics>
  <trace>
    <listeners>
      <remove name="Default"/>
      <add name="ExceptionListener" type="Namespace.ExceptionTraceListener,AssemblyName"/>
    </listeners>
  </trace>
 </system.diagnostics>

C# 및 .NET에있는 방법은 모르겠지만 C에서는 -ddebug로 컴파일 된 경우에만 작동합니다. 엔더 서서는 assert ()가 없으면 Assert ()를 보지 못합니다. 개발자만을위한 것입니다. 나는 자주 사용하는 경우가 종종 있습니다. 때로는 버그를 추적하는 것이 더 쉽습니다.

나는 그것들을 생산 코드에서 사용하지 않을 것입니다. 예외를 던지고 캐치 및 로그를 던집니다.

또한 ASP.NET에서는 콘솔에 표시되어 요청을 동결 할 수 있으므로 ASP.NET에서 조심해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top