Kode "Debug saja" yang seharusnya berjalan hanya saat "diaktifkan"


94

Saya ingin menambahkan beberapa kode C # "hanya debug" yang hanya berjalan jika orang yang men-debug memintanya. Di C ++, saya biasa melakukan sesuatu yang mirip dengan berikut ini:

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
 // ...
}

Saya tidak bisa melakukan hal yang sama di C # karena tidak ada statika lokal.

Pertanyaan : Apa cara terbaik untuk mencapai ini di C #?

  1. Haruskah saya menggunakan bidang statis kelas privat dengan arahan preprocessor C # ( #if/#endif DEBUG)?
  2. Haruskah saya menggunakan atribut Conditional (untuk menyimpan kode), dan kemudian bidang statis kelas privat ( tidak dikelilingi oleh arahan preprocessor C # #if/#endif DEBUG?).
  3. Sesuatu yang lain?

Jawaban:


147

Variabel contoh mungkin adalah cara untuk melakukan apa yang Anda inginkan. Anda dapat menjadikannya statis untuk mempertahankan nilai yang sama selama masa pakai program (atau utas bergantung pada model memori statis Anda), atau menjadikannya sebagai var instance biasa untuk mengontrolnya selama masa pakai instance objek. Jika instance itu tunggal, mereka akan berperilaku dengan cara yang sama.

#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
 // ...
}

Untuk melengkapi, pragma (arahan preprocessor) dianggap sedikit kludge untuk digunakan untuk mengontrol aliran program. .NET memiliki jawaban built-in untuk setengah dari masalah ini, menggunakan atribut "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.
  }    
  // ...
}

Tidak ada pragma, lebih bersih. Kekurangannya adalah Conditional hanya bisa diterapkan ke metode, jadi Anda harus berurusan dengan variabel boolean yang tidak melakukan apa pun dalam build rilis. Karena variabel hanya ada untuk diubah dari host eksekusi VS, dan dalam rilis build nilainya tidak masalah, itu tidak berbahaya.


2
Akhirnya - seseorang yang membaca seluruh pertanyaan. Terima kasih, oke - sepertinya solusi yang panjang (harus memiliki dua bagian preprocessor), tapi mungkin itu yang terbaik yang bisa dilakukan C # untuk apa yang saya inginkan.
Matt Smith

6
meh. Saya tidak akan menyebutnya panjang hanya karena Anda menambahkan dua baris arahan preprocessor.
KeithS

4
Terima kasih banyak, Patrick, karena tidak menyukai jawaban yang diterima anak berusia 3 tahun dan mendukung jawaban yang tidak menyelesaikan seluruh masalah. Atribut kondisional hanya mencegah metode yang dijalankan dalam mode non-debug. OP tidak hanya menginginkan itu, tetapi juga dapat "mengaktifkan" kode menggunakan debugger. Dan, tag gokkor sebagai bekas tidak akan dikompilasi.
KeithS

2
Perhatikan bahwa preprocessor memberi tahu Anda apakah program sedang dikompilasi dalam mode debug, tetapi tidak apakah debugger benar-benar berjalan.
Shane

65

Apa yang Anda cari adalah

[ConditionalAttribute("DEBUG")]

atribut.

Jika Anda misalnya menulis metode seperti:

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

panggilan apa pun yang Anda lakukan ke metode ini di dalam kode Anda sendiri hanya akan dijalankan dalam mode debug. Jika Anda membangun proyek Anda dalam mode rilis, bahkan panggilan ke "MyLovelyDebugInfoMethod" akan diabaikan dan dibuang dari biner Anda.

Oh dan satu hal lagi jika Anda mencoba untuk menentukan apakah kode Anda saat ini sedang di-debug atau tidak pada saat eksekusi, Anda juga dapat memeriksa apakah proses saat ini terkait dengan JIT. Tapi ini semua adalah kasus lain. Kirim komentar jika ini yang Anda coba lakukan.


3
Saat menggunakan Atribut, Anda tidak harus menulis sufiks "Atribut". Conditional = ConditionalAttribute. Kelas atribut harus diakhiri dengan "Atribut" tetapi dapat dihilangkan ketika digunakan sebagai atribut dalam kode. Lebih mudah dibaca jika sufiks dihilangkan.
Eric Ouellet

23

Anda dapat mencoba ini jika Anda hanya memerlukan kode untuk dijalankan saat Anda memiliki debugger yang terpasang ke proses tersebut.

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

Terima kasih! Inilah yang saya inginkan: Lakukan Console.ReadLine () di bagian akhir untuk mencegah penutupan jendela konsol saat debugging.
VVS

4

Saya pikir mungkin perlu disebutkan bahwa [ConditionalAttribute]ada di System.Diagnostics;namespace. Saya sedikit tersandung ketika saya mendapat:

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

setelah menggunakannya untuk pertama kali (saya pikir itu akan masuk System).


3

Jika Anda ingin tahu apakah debugging, di mana-mana dalam program. Gunakan ini.

Deklarasikan variabel global.

bool isDebug=false;

Buat fungsi untuk memeriksa mode debug

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

Dalam metode inisialisasi, panggil fungsi

isDebugging();

Sekarang di seluruh program. Anda dapat memeriksa debugging dan melakukan operasi. Semoga ini membantu!


1
AFAIK: ini dan variannya hanya cara yang pasti untuk mengetahui apakah program wash dikompilasi dengan set flag debug.
LosManos
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.