2009-11-03 5 views
1

Dans une classe, j'ai une méthode de trace qui ressemble à ceci:System.Diagnostics.ConditionalAttribute et conditionnellement compilation types et les variables de soutien

[System.Diagnostics.ConditionalAttribute("Trace")] 
    private void TraceOutput(TraceBits bits, string format, params object[] varParams) 
    { 
     if ((bits & _DesiredTrace) != 0) 
     { 
      ...emit trace here... 
     } 
    } 

Tracebits est un [Flags] enum. Chaque appel à TraceOutput transmet le bit avec lequel l'appel est marqué. Comme ceci:

TraceOutput(TraceBits.Fill, 
       "Fill  lock  wi({0}) stat({1}) iba({2}) nf({3})", 
       workitem.index, 
       workitem.status, 
       workitem.inputBytesAvailable, 
       _nextToFill 
       ); 

Les bits sont: Create, Read, Write, remplissage, etc. _DesiredTrace est un (membre privé) bitfield qui indique que les déclarations de trace doivent être effectivement émis. De cette façon, je peux sélectivement activer les instructions de trace pour diverses parties de la fonction au sein de la classe. Si je veux suivre uniquement la construction et la destruction, je mets le bit Create dans ce bitfield membre.

Je peux utiliser le ConditionalAttribute sur la méthode, mais cet attribut ne fonctionne pas sur les variables membres ou les types imbriqués (comme TraceBits). Par conséquent, les types et les variables qui prennent en charge le suivi sont compilés dans le code, que le Trace soit défini ou non. Si le suivi n'est pas défini, ils sont complètement inutiles.

Existe-t-il un moyen propre de compiler conditionnellement les types et variables pris en charge?

Je sais que je peux utiliser #if Trace ... #endif pour entourer la déclaration et toutes les invocations de TraceOutput, ainsi que toutes les choses de support, mais cela gêne le code. J'aime l'aspect plus propre du ConditionalAttribute, où chaque appel à TraceOutput n'a pas besoin d'être entouré de #if Trace. Ce que je veux vraiment, c'est un moyen d'utiliser cet attribut, ou quelque chose comme ça, sur les classes imbriquées et les variables membres. Est-ce possible?

Répondre

2

Re l'énumération; le point à propos de [Conditional] est que c'est à la caller de construire s'il faut réellement effectuer l'invocation - le déclarant/implémenter le code est toujours inclus; Supposons donc que votre code est une bibliothèque autonome; doit inclure l'énumération, sinon l'appelant (supposons que l'appelant est séparé) ne peut pas éventuellement jamais appeler la méthode. Il semble que #if soit mieux adapté à votre problème - ou vous pouvez utiliser une inclusion conditionnelle dans la construction (csproj supporte cela, bien que cela risque de causer de la confusion, #if serait plus évident).

Notez que pour effectuer une résolution de surcharge, il faut d'abord identifier les types, donc vous ne pouvez pas vraiment mélanger #if avec [Conditional] puisque l'énumération est dans la signature.

Questions connexes