2009-09-17 8 views
9

Est-il possible de créer une méthode qui effectue une assistance de débogage comme la classe System.Diagnostics.Debug?Est-il possible de créer une méthode Debug uniquement dans .NET?

Je cherche un moyen de construire une méthode qui, lorsqu'elle est appelée par un assembly compilé avec le symbole de compilation conditionnel DEBUG défini, aboutit à une opération, et qui est une no-op lorsqu'elle est appelée par un assembly sans le symbole défini.

Si possible, j'aimerais que les appels aux méthodes de débogage permettent d'ajouter un surcoût minimal ou d'augmenter la taille de la version finale de l'assembly. Pour clarifier, les méthodes de débogage doivent être dans un assembly compilé en mode Release. Les appels aux méthodes ne doivent générer des opérations que s'ils sont appelés à partir d'un assembly avec le symbole DEBUG défini dans la portée de l'appel de méthode.

Répondre

30

Ajouter la Conditional attribut à la méthode, comme ceci:

[Conditional("DEBUG")] 
public void Whatever() { 
    //... 
} 

Notez que e La méthode doit renvoyer void et ne peut avoir aucun paramètre out; sinon, il serait impossible de supprimer un appel.

La méthode sera compilée dans l'assembly, mais les compilateurs compatibles CLS n'émettront des appels à la méthode que si les assemblages qu'ils compilent ont défini DEBUG. Notez que le compilateur C++ n'est pas compatible CLS et émettra toujours l'appel.

+0

+1 de remarquer que ce conditionnelle est pas à toute épreuve (ce que cela signifie qu'il est encore CLI-conforme?) Que se passe-C++ appelle à Debug.WriteLine? Est-ce que c'est pour toutes les versions? Ça serait sympa de vous faire éditer ça dans: P –

+0

Je ne l'ai pas vraiment essayé. La page MSDN sur ConditionalAttribute indique simplement que le compilateur C++ n'est pas conforme, sans indiquer quelles versions. – SLaks

+0

Comme je l'ai dit dans la réponse ('et émettra toujours l'appel'), le compilateur C++ (je crois) émettra toujours des appels à' WriteLine', même dans Release. – SLaks

3

Si vous démontez la classe System.Diagnostics.Debug utilisant Reflector vous pouvez voir que cela se fait en utilisant l'attribut [Conditional("DEBUG")]:

public sealed class Debug 
{ 
    private Debug(); 
    [Conditional("DEBUG")] 
    public static void Assert(bool condition); 
    // etc... 
} 
1

Si vous avez besoin d'une autre signature que void Func (..) sans paramètres, à la ce serait mal à

MyDebugObject Foo(out int justForGrins) 
{ 
    justForGrins = <safe value for release builds>; 
    MyDebugObject result = <safe value for release builds>; 
    #if DEBUG 
    .. run code you need for your debugging... 
    #endif 
    return result; 
} 

il est plus bavard et moins élégant que le ConditionalAttribute, mais il vous permettra une signature plus souple.

0

Pourquoi ne pas essayer quelque chose comme ça?

#if DEBUG 
     private void DebugLog(string message) 
     { 
      // do whatever u want. 
     } 
#endif 
+0

Cela crée un problème où la méthode n'existe pas lors de la compilation sous une construction non-debug.Tout code essayant d'appeler cette méthode ne serait alors pas compilé. La classe 'Debug' a des méthodes que vous pouvez appeler à partir du code de débogage, mais auxquelles les appels sont supprimés lors de la compilation du code de version. –

+0

@Tragedian - ooPS! –

+0

@Tragedian Même avec les problèmes que vous mentionnez, cela peut être une solution supérieure dans certaines circonstances. C'est une réponse valable tant que ce que vous avez mentionné est pris en compte. –

Questions connexes