"설정"된 경우에만 실행해야하는 "디버그 전용"코드


93

디버깅하는 사람이 요청하는 경우에만 실행되는 일부 C # "디버그 전용"코드를 추가하고 싶습니다. C ++에서는 다음과 비슷한 작업을 수행했습니다.

void foo()
{   
  // ...
  #ifdef DEBUG
  static bool s_bDoDebugOnlyCode = false;
  if (s_bDoDebugOnlyCode)
  {
      // Debug only code here gets executed when the person debugging 
      // manually sets the bool above to true.  It then stays for the rest
      // of the session until they set it to false.
  }
  #endif
 // ...
}

로컬 정적이 없기 때문에 C #에서 똑같이 할 수는 없습니다.

질문 : C #에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

  1. C # 전 처리기 지시문 ( #if/#endif DEBUG) 과 함께 개인 클래스 정적 필드를 사용해야 합니까?
  2. Conditional 특성 (코드를 보유하기 위해)을 사용하고 개인 클래스 정적 필드 ( C # 전 처리기 지시문으로 둘러싸여 있지 않음 )를 사용해야합니다 #if/#endif DEBUG.
  3. 다른 것?

답변:


145

인스턴스 변수는 아마도 원하는 것을 수행하는 방법 일 것입니다. 프로그램 (또는 정적 메모리 모델에 따라 스레드)의 수명 동안 동일한 값을 유지하도록 정적으로 만들거나 객체 인스턴스의 수명 동안 제어하기 위해 일반 인스턴스 var로 만들 수 있습니다. 해당 인스턴스가 싱글 톤이면 동일한 방식으로 작동합니다.

#if DEBUG
private /*static*/ bool s_bDoDebugOnlyCode = false;
#endif

void foo()
{   
  // ...
#if DEBUG
  if (s_bDoDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }
#endif
 // ...
}

간단히 말해서, pragma (전 처리기 지시문)는 프로그램 흐름을 제어하는 ​​데 사용하는 약간의 문제로 간주됩니다. .NET에는 "Conditional"속성을 사용하여이 문제의 절반에 대한 기본 제공 답변이 있습니다.

private /*static*/ bool doDebugOnlyCode = false; 
[Conditional("DEBUG")]
void foo()
{   
  // ...    
  if (doDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }    
  // ...
}

pragma는없고 훨씬 깨끗합니다. 단점은 Conditional이 메서드에만 적용될 수 있으므로 릴리스 빌드에서 아무 작업도하지 않는 부울 변수를 처리해야한다는 것입니다. 변수는 VS 실행 호스트에서 토글하기 위해서만 존재하며 릴리스 빌드에서는 그 값이 중요하지 않으므로 꽤 무해합니다.


2
마지막으로 전체 질문 을 읽은 사람 . 고마워, 좋아. (두 개의 전 처리기 섹션이 있어야하는) 일종의 긴 솔루션처럼 보였지만 아마도 내가 원하는 것을 위해 할 수있는 최고의 C # 일 것이다.
Matt Smith

6
meh. 전 처리기 지시문을 두 줄 더 추가했기 때문에 이것을 길게 부르지 않을 것입니다.
KeithS

4
전체 문제를 해결하지 못하는 답변에 찬성하여 3 년 동안 받아 들여진 답변에 반대 투표를 해주신 Patrick에게 대단히 감사합니다. 조건부 속성은 비디 버그 모드에서만 메서드가 실행되는 것을 방지합니다. OP는 그뿐만 아니라 디버거를 사용하여 코드를 "켜기"를 원했습니다. 그리고 사용 된 gokkor의 태그는 컴파일되지 않습니다.
KeithS

2
전처리 기는 프로그램이 디버그 모드에서 컴파일되고 있는지 여부를 알려 주지만 디버거가 실제로 실행 중인지 여부는 알 수 없습니다.
Shane

65

당신이 찾고있는 것은

[ConditionalAttribute("DEBUG")]

속성.

예를 들어 다음과 같은 메소드를 작성하면

[ConditionalAttribute("DEBUG")]
public static void MyLovelyDebugInfoMethod(string message)
{
    Console.WriteLine("This message was brought to you by your debugger : ");
    Console.WriteLine(message);
}

자체 코드 내에서이 메서드에 대한 호출은 디버그 모드에서만 실행됩니다. 릴리스 모드에서 프로젝트를 빌드하는 경우 "MyLovelyDebugInfoMethod"에 대한 호출도 무시되고 바이너리에서 덤프됩니다.

아 그리고 한 가지 더 코드가 실행 순간에 현재 디버깅되고 있는지 여부를 확인하려는 경우 현재 프로세스가 JIT에 의해 후크되어 있는지 확인할 수도 있습니다. 그러나 이것은 모두 함께 또 다른 경우입니다. 이것이 당신이하려는 일이라면 코멘트를 게시하십시오.


3
속성을 사용할 때 접미사 "속성"을 쓸 필요가 없습니다. Conditional = ConditionalAttribute. 속성 클래스는 "Attribute"로 끝나야하지만 코드에서 속성으로 사용되는 경우 생략 할 수 있습니다. 접미사가 생략되면 읽기가 더 쉽습니다.
Eric Ouellet 2019

23

프로세스에 디버거가 연결되어있을 때만 코드를 실행해야하는 경우이를 시도 할 수 있습니다.

if (Debugger.IsAttached)
{
     // do some stuff here
}

감사합니다! 이것이 바로 내가 원했던 것입니다. 디버깅 할 때 콘솔 창을 닫지 않도록 끝에 Console.ReadLine ()을 수행합니다.
VVS

4

나는 그것이 네임 스페이스 [ConditionalAttribute]에 있음을 언급 할 가치가 있다고 생각합니다 System.Diagnostics;. 나는 다음을 얻었을 때 약간 넘어졌습니다.

Error 2 The type or namespace name 'ConditionalAttribute' could not be found (are you missing a using directive or an assembly reference?)

처음 사용한 후 (내 생각에는 System).


3

디버깅 여부를 알고 싶다면 프로그램의 모든 곳에서. 이것을 사용하십시오.

전역 변수를 선언하십시오.

bool isDebug=false;

디버그 모드 확인 기능 생성

[ConditionalAttribute("DEBUG")]
    public static void isDebugging()
    {
        isDebug = true;
    }

initialize 메소드에서 함수를 호출하십시오.

isDebugging();

이제 전체 프로그램에서. 디버깅을 확인하고 작업을 수행 할 수 있습니다. 도움이 되었기를 바랍니다!


1
AFAIK : 이것과 여기의 변형은 프로그램 세척 이 디버그 플래그 세트로 컴파일 되었는지 알 수있는 확실한 방법 입니다.
LosManos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.