Programing

C # if / then 지시어 대 디버그 대 릴리스

lottogame 2020. 2. 23. 11:32
반응형

C # if / then 지시어 대 디버그 대 릴리스


솔루션 속성에서 하나의 유일한 프로젝트에 대해 구성을 "릴리스"로 설정했습니다.

메인 루틴의 시작 부분 에이 코드가 있으며 "Mode = Debug"가 표시됩니다. 또한 맨 위에 두 줄이 있습니다.

#define DEBUG 
#define RELEASE

올바른 변수를 테스트하고 있습니까?

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

내 목표는 디버그 모드와 릴리스 모드를 기반으로 변수에 다른 기본값을 설정하는 것입니다.


#define DEBUG코드에서를 제거하십시오 . 해당 특정 빌드에 대한 빌드 구성에서 프리 프로세서를 설정하십시오 (DEBUG / _DEBUG는 이미 VS에 정의되어 있어야 함).

그것은 "모드 = 디버그"인쇄 이유 때문에 당신입니다 #define다음 건너 뜁니다 elif.

또한 올바른 확인 방법은 다음과 같습니다.

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

릴리스 확인하지 마십시오


기본적으로 Visual Studio는 프로젝트가 디버그 모드로 컴파일 된 경우 DEBUG를 정의하고 릴리스 모드 인 경우에는 정의하지 않습니다. 릴리스 모드에서는 RELEASE가 기본적으로 정의되어 있지 않습니다. 다음과 같이 사용하십시오 :

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif

릴리스 모드에서만 무언가를 수행하려는 경우 :

#if !DEBUG
  // release...
#endif

또한 특정 심볼이 정의 된 경우에만 [Conditional("DEBUG")]반환 void되도록 메소드에 속성을 사용할 수 있음을 지적하는 것이 좋습니다 . 심볼이 정의되지 않은 경우 컴파일러는 해당 메소드에 대한 모든 호출을 제거합니다.

[Conditional("DEBUG")]
void PrintLog() {
    Console.WriteLine("Debug info");
}

void Test() {
    PrintLog();
}

#defines를 찾는 것과 같이 이것을 선호합니다.

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

물론 경고 모드를 사용하면 디버그 모드에서 무언가를 컴파일하고 배포 할 수 있지만 여전히 디버거가 연결되지는 않습니다.


특히 #if에 대한 열렬한 팬이 아닙니다. 특히 디버그 빌드가 통과하지만주의하지 않으면 릴리스 빌드가 실패하는 경우 문제가 발생하므로 코드베이스에 모두 퍼뜨릴 경우 특히 그렇습니다.

그래서 여기에 내가 생각해 낸 것이 있습니다 ( C #의 #ifdef에서 영감을 얻음 ).

public interface IDebuggingService
{
    bool RunningInDebugMode();
}

public class DebuggingService : IDebuggingService
{
    private bool debugging;

    public bool RunningInDebugMode()
    {
        //#if DEBUG
        //return true;
        //#else
        //return false;
        //#endif
        WellAreWe();
        return debugging;
    }

    [Conditional("DEBUG")]
    private void WellAreWe()
    {
        debugging = true;
    }
}

bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

이 메소드 Debug.Assert에는 조건부 속성이 DEBUG있습니다. 정의되지 않은 경우 통화 및 할당 isDebug = true제거됩니다 .

기호가 정의되면 통화가 포함됩니다. 그렇지 않으면 호출 (호출 매개 변수 평가 포함)이 생략됩니다.

경우 DEBUG정의, isDebug로 설정 true(및 전달 Debug.Assert이 경우에 아무것도 안하는).


빌드 유형에 정의 된 변수를 사용하려는 경우 두 줄을 제거해야합니다.

#define DEBUG  
#define RELEASE 

... 이렇게하면 #if (DEBUG) 가 항상 참이됩니다.

또한 RELEASE에 대한 기본 조건부 컴파일 기호가 없습니다 . 프로젝트 속성으로 정의하려면 빌드 탭을 클릭 한 다음 일반 표제 아래의 조건부 컴파일 기호 텍스트 상자에 RELEASE를 추가하십시오 .

다른 옵션은 이것을하는 것입니다 ...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif

상단에서 당신의 정의를 제거

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif

Tod Thomson의 답변을 별도의 클래스가 아닌 정적 함수로 약간 수정 (개별화 되었습니까?) 한 버전 (이미 포함 된 viewutils 클래스의 WebForm 뷰 바인딩에서 호출 할 수 있기를 원했습니다).

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}

네임 스페이스

using System.Resources;
using System.Diagnostics;

방법

   private static bool IsDebug()
    {
        object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
        if ((customAttributes != null) && (customAttributes.Length == 1))
        {
            DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
            return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
        }
        return false;
    }

프로젝트 빌드 속성에서 DEBUG 상수를 정의해야합니다. 을 활성화합니다 #if DEBUG. 미리 정의 된 RELEASE 상수가 표시되지 않으므로 DEBUG 블록에없는 것이 RELEASE 모드임을 암시 할 수 있습니다.

프로젝트 빌드 속성에서 DEBUG 상수 정의


많은 시간을 절약 할 수있는 팁- debug빌드 구성 (2012/13 메뉴에서 BUILD => CONFIGURATION MANAGER 아래에 있음)에서 선택하더라도 충분하지 않습니다.

다음 Configuration과 같이 PUBLISH에주의해야합니다 .

여기에 이미지 설명을 입력하십시오


이러한 COMPILER 지시문의 목적은 컴파일러에게 광고 부서 (예 : #Define AdDept)를 제외하고 모든 최종 사용자가 필요로하는 코드, 디버그 코드, 베타 코드 또는 코드를 포함하지 않도록 지시하는 것입니다. 필요에 따라 포함하거나 제거 할 수 있습니다. 예를 들어 비 AdDept가 AdDept에 병합되는 경우 소스 코드를 변경할 필요가 없습니다. 그런 다음 기존 버전의 프로그램의 컴파일러 옵션 속성 페이지에 #AdDept 지시문을 포함시키고 컴파일 및 실행을 수행하면됩니다. 병합 된 프로그램의 코드가 생생합니다!.

프라임 타임에 준비되지 않았거나 릴리스 할 때까지 코드에서 활성화 할 수없는 새 프로세스에 대해 선언을 사용할 수도 있습니다.

어쨌든, 그것이 내가하는 방식입니다.


더 나은 방법을 생각해야했습니다. #if 블록이 다른 구성에서 효과적으로 주석이라고 생각합니다 ( DEBUG또는 가정 RELEASE하지만 기호가 있으면 참).

public class Mytest
    {
        public DateTime DateAndTimeOfTransaction;
    }

    public void ProcessCommand(Mytest Command)
        {
            CheckMyCommandPreconditions(Command);
            // do more stuff with Command...
        }

        [Conditional("DEBUG")]
        private static void CheckMyCommandPreconditions(Mytest Command)
        {
            if (Command.DateAndTimeOfTransaction > DateTime.Now)
                throw new InvalidOperationException("DateTime expected to be in the past");
        }

정의를 제거하고 조건이 디버그 모드인지 확인하십시오. 지시문이 릴리스 모드인지 확인하지 않아도됩니다.

이 같은:

#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

참고 URL : https://stackoverflow.com/questions/2104099/c-sharp-if-then-directives-for-debug-vs-release



반응형