web-dev-qa-db-ja.com

デバッグとリリースのC#if / thenディレクティブ

ソリューションのプロパティで、私の唯一のプロジェクトのConfigurationを "release"に設定します。

メインルーチンの始めに、私はこのコードを持っていて、それは "Mode = Debug"を示しています。この2行も一番上にあります。

#define DEBUG 
#define RELEASE

正しい変数をテストしていますか?

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

私の目標は、デバッグモードとリリースモードに基づいて、変数に異なるデフォルトを設定することです。

384
NealWalters

コードから#define DEBUGを削除してください。その特定のビルドのビルド構成にプリプロセッサーを設定します(DEBUG/_DEBUGはすでにVSで定義されているはずです)。

「Mode = Debug」と表示されるのは、#defineが原因でElifがスキップされるからです。

また、確認する正しい方法は次のとおりです。

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

RELEASEをチェックしない

642
psychotik

デフォルトでは、プロジェクトがデバッグモードでコンパイルされている場合、Visual StudioはDEBUGを定義し、リリースモードである場合は定義しません。 RELEASEは、デフォルトではリリースモードでは定義されていません。このようなものを使う:

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

リリースモードでのみ何かしたい場合は、

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

また、voidを返すメソッドに[Conditional("DEBUG")]属性を使用して、特定のシンボルが定義されている場合にのみそれらを実行できるようにすることもできます。シンボルが定義されていない場合、コンパイラはこれらのメソッドへの呼び出しをすべて削除します。

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

void Test() {
    PrintLog();
}
270
Mehrdad Afshari

#definesを探すのではなく、このようにチェックするのが好きです。

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

当然のことながら、デバッグモードで何かをコンパイルしてデプロイすることはできますが、それでもデバッガはアタッチされません。

182
Joel Coehoorn

私は#ifの大ファンではありません、特にあなたがそれをあなたのコードベース全体に広げているならば、Debugビルドは成功するがReleaseビルドは失敗する問題をあなたに与えるので注意してください。

だからここに私が思いついたものがあります(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;
    }
}
49
Tod Thomson
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

メソッド Debug.Assert は、条件付き属性DEBUGを持ちます。定義されていない場合、呼び出しと代入isDebug = true削除されます

シンボルが定義されている場合、呼び出しは含まれています。それ以外の場合、呼び出し(呼び出しのパラメーターの評価を含む)は省略されます。

DEBUGが定義されている場合、isDebugtrueに設定されます(そしてDebug.Assertに渡されますが、その場合は何もしません)。

20
AlexD

ビルドタイプに定義されている変数を使用しようとしている場合は、2行を削除する必要があります。

#define DEBUG  
#define RELEASE 

...これは#if(DEBUG)が常に真になるようにします。

RELEASEのデフォルトの条件付きコンパイルシンボルもありません。定義したい場合は、プロジェクトのプロパティに行き、ビルドタブをクリックしてから、条件付きコンパイルシンボルにRELEASEを追加します一般見出しの下のテキストボックス。

他のオプションはこれをすることです...

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

上部の定義を削除してください

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

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;
}
7
LocalPCGuy

プロジェクトビルドプロパティでDEBUG定数を必ず定義してください。これで#if DEBUGが有効になります。定義済みのRELEASE定数が表示されないため、DEBUGブロック内にないものはすべてRELEASEモードになっている可能性があります。

Define DEBUG constant in Project Build Properties

4
gridtrak

ネームスペース

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;
    }
4
Ehsan Enaloo

あなたが多くの時間を節約するかもしれない助言 - あなたが(vs2012/13メニューでそれがBUILD => CONFIGURATION MANAGERの下で)ビルド設定の下でdebugを選んだとしても - それは十分ではないことを忘れないでください。

以下のようなPUBLISH Configurationに注意を払う必要があります。

enter image description here

3
ilans

もっと良い方法を考えました。 #ifブロックは、他の構成では効果的にコメントであることがわかりました(DEBUGまたはRELEASE;が、どのシンボルでもtrueであると仮定)

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");
        }
0
user11773533

これらのCOMPILERディレクティブの目的は、広告部門、つまり#Define AdDept以外のすべてのエンドユーザーが必要とするコード、デバッグコード、ベータコード、またはコードを含めないようにコンパイラーに指示することです。必要に応じてそれらを含めたり削除したりできます。たとえば、非AdDeptがAdDeptにマージされても、ソースコードを変更する必要はありません。それから、#AdDeptディレクティブを既存バージョンのプログラムのコンパイラー・オプション・プロパティー・ページに組み込み、コンパイルしてワラするだけです。マージされたプログラムのコードは生きています!.

また、プライムタイムの準備ができていない、またはリリースするまでコード内でアクティブにできない新しいプロセスに対して宣言を使用することもできます。

とにかく、それが私のやり方です。

0
mrMagik3805

定義を削除し、条件がデバッグモードになっているかどうかを確認します。ディレクティブがリリースモードになっているかどうかを確認する必要はありません。

このようなもの:

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