Yalnızca "açıldığında" çalıştırılması gereken "Yalnızca hata ayıklama" kodu


94

Yalnızca hata ayıklayan kişi isterse çalıştıran bazı C # "yalnızca hata ayıklama" kodunu eklemek istiyorum. C ++ 'da, aşağıdakine benzer bir şey yapardım:

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

Yerel statik olmadığı için C #'da tam olarak aynısını yapamam.

Soru : Bunu C # ile gerçekleştirmenin en iyi yolu nedir?

  1. C # önişlemci yönergeleri ( #if/#endif DEBUG) ile özel bir sınıf statik alan kullanmalı mıyım ?
  2. Koşullu özniteliği (kodu tutmak için) ve sonra özel bir sınıf statik alanını ( C # önişlemci yönergeleriyle çevrili değil#if/#endif DEBUG mi?) Kullanmalı mıyım?
  3. Başka bir şey?

Yanıtlar:


148

Bir örnek değişkeni muhtemelen istediğinizi yapmanın yolu olacaktır. Programın ömrü boyunca aynı değeri sürdürmeyi (veya statik bellek modelinize bağlı olarak iş parçacığı) statik hale getirebilir veya bir nesne örneğinin ömrü boyunca onu kontrol etmek için sıradan bir örnek varyasyonu yapabilirsiniz. Bu örnek bir singleton ise, aynı şekilde davranacaklardır.

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

Eksiksiz olmak gerekirse, pragmalar (önişlemci yönergeleri), program akışını kontrol etmek için kullanılacak biraz kludge olarak kabul edilir. .NET, bu sorunun yarısı için "Koşullu" özniteliğini kullanan yerleşik bir cevaba sahiptir.

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 yok, daha temiz. Olumsuz yanı, Koşullu'nun yalnızca yöntemlere uygulanabilmesidir, bu nedenle sürüm yapısında hiçbir şey yapmayan bir boole değişkeni ile uğraşmanız gerekir. Değişken yalnızca VS yürütme ana bilgisayarından değiştirilmek üzere bulunduğundan ve bir sürümde derlemede değeri önemli değil, oldukça zararsızdır.


2
Son olarak - tüm soruyu okuyan biri . Teşekkürler, tamam - bu biraz uzun bir çözüm gibi görünüyordu (iki önişlemci bölümüne sahip olmak zorunda), ama belki de istediğim şey için C #'ın yapabileceği en iyi şey bu.
Matt Smith

7
meh. İki satır daha önişlemci yönergesi eklediğiniz için buna uzun demezdim.
KeithS

4
Pekala Patrick, 3 yaşındaki bir çocuğun kabul ettiği bir yanıtı, tüm sorunu çözmeyen bir yanıt lehine olumsuz oyladığı için çok teşekkür ederim. Koşullu öznitelik yalnızca yöntemin hata ayıklama olmayan modlarda yürütülmesini engeller. OP sadece bunu değil, aynı zamanda hata ayıklayıcıyı kullanarak kodu "açabilmeyi" istedi. Ve gokkor'un kullanılan etiketi derlenmez.
KeithS

2
Önişlemcinin size programın hata ayıklama modunda derlenip derlenmediğini söylediğini, ancak hata ayıklayıcının gerçekten çalışıp çalışmadığını söylemediğini unutmayın.
Shane

66

Aradığınız şey

[ConditionalAttribute("DEBUG")]

öznitelik.

Örneğin, aşağıdaki gibi bir yöntem yazarsanız:

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

kendi kodunuz içinde bu yönteme yaptığınız herhangi bir çağrı yalnızca hata ayıklama modunda yürütülecektir. Projenizi yayınlama modunda oluşturursanız, "MyLovelyDebugInfoMethod" çağrısı bile yok sayılacak ve ikili programınızdan atılacaktır.

Oh ve bir şey daha, kodunuzun şu anda çalıştırma anında hata ayıklanıp ayıklanmadığını belirlemeye çalışıyorsanız, mevcut işlemin bir JIT tarafından bağlanıp bağlanmadığını kontrol etmek de mümkündür. Ama bu hep birlikte başka bir durum. Yapmaya çalıştığınız şey buysa bir yorum gönderin.


5
Öznitelik kullanırken, "Öznitelik" sonekini yazmanıza gerek yoktur. Koşullu = ConditionalAttribute. Bir öznitelik sınıfı "Öznitelik" ile bitmelidir, ancak kodda bir öznitelik olarak kullanıldığında atlanabilir. Sonek atlandığında okumak daha kolaydır.
Eric Ouellet

23

Yalnızca işleme eklenmiş bir hata ayıklayıcınız varken çalıştırılacak koda ihtiyacınız varsa bunu deneyebilirsiniz.

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

Teşekkür ederim! Tam olarak istediğim buydu: Hata ayıklama sırasında konsol penceresinin kapanmasını önlemek için sonunda bir Console.ReadLine () yapın.
VVS

4

Bunun isim alanında [ConditionalAttribute]olduğundan bahsetmeye değer olduğunu düşünüyorum System.Diagnostics;. Elimde biraz tökezledim:

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

ilk kez kullandıktan sonra (içinde olacağını düşündüm System).


3

Programın her yerinde hata ayıklama olup olmadığını bilmek istiyorsanız. Bunu kullan.

Global değişkeni bildirin.

bool isDebug=false;

Hata ayıklama modunu kontrol etmek için işlev oluşturun

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

Başlatma yönteminde işlevi çağırın

isDebugging();

Şimdi tüm programda. Hata ayıklamayı kontrol edebilir ve işlemleri yapabilirsiniz. Bu yardımcı olur umarım!


1
AFAIK: Bu ve bunun varyantları , hata ayıklama bayrağı ayarlı bir program yıkamasının derlenmiş olup olmadığını bilmenin yalnızca kesin yoludur .
LosManos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.