catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
For now, ignore the fact that you will only see output using something like DebugView. The real problem is that when the code is compiled in Release mode, calls to Debug.WriteLine are removed completely. So in the example above, the catch block will be empty.
To reduce the odds of this sort of thing happening in the future, I decided to write a custom FxCop rule to locate any calls to methods that had been tagged with a "Debug" conditional. It wasn't as easy as I had expected, but there is an excellent tutorial on the subject. The only difficulty I had was in locating the ConditionalSymbol property in the class tree.
For anyone interested, here is the xml rule file:
<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Custom Rules">
<Rule TypeName="DoNotCallDebugConditionalMethods" Category="CustomRules" CheckId="PG1001">
<Name>Do not call debug conditional methods</Name>
<Description>Calls to methods marked with the DEBUG conditional will be removed
from Release builds.</Description>
<Url></Url>
<Resolution>Replace the call to '{0}' with a more appropriate call</Resolution>
<MessageLevel Certainty="100">Warning</MessageLevel>
<Email></Email>
<FixCategories>DependsOnFix</FixCategories>
<Owner></Owner>
</Rule>
</Rules>
And the code:
namespace CustomFxCopRules
{
/// <summary>
/// Warns of any methods being called that are removed from non-debug builds,
/// such as Debug.WriteLine()
/// </summary>
public class DoNotCallDebugConditionalMethods : BaseIntrospectionRule
{
public DoNotCallDebugConditionalMethods()
: base("DoNotCallDebugConditionalMethods", "CustomFxCopRules.rules.xml",
typeof(DoNotCallDebugConditionalMethods).Assembly)
{ }
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method != null)
{
VisitStatements(method.Body.Statements);
}
return Problems;
}
public override void VisitMethodCall(MethodCall call)
{
var member = ((MemberBinding)call.Callee).BoundMember;
var method = (Method)member;
var symbol = method.ConditionalSymbol;
if (!string.IsNullOrEmpty(symbol) && symbol.Contains("DEBUG"))
{
Problems.Add(new Problem(GetResolution(method.FullName), call.SourceContext));
}
}
}
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.