C#编译器如何删除发布版本中的Debug.Assert?我最近浏览了一些代码,思考是否需要小心处理Debug.Assert语句中的表达式,例如昂贵的操作或具有副作用的表达式。但是,看起来编译器非常聪明地完全删除了Assert语句和内部表达式。例如,以下仅在调试版本上打印:staticvoidMain(string[]args){Debug.Assert(SideEffect());}privatestaticboolSideEffect(){Console.WriteLine("副作用!");返回真;}这会抱怨在发布版本初始化之前正在使用o:staticvoidMain(string[]args){objecto;Debug.Assert(初始化(outo));o.ToString();}privatestaticboolInitialize(outobjecto){o=newobject();返回真;它甚至可以表达这样的表达式(在两种情况下都打印“After”):staticvoidMain(string[]args){if(false)Debug.Assert(true);Console.WriteLine("之后");我对编译器的智能程度以及在删除Debug.Assert时正确检测案例的能力感到有些惊讶。所以,这让我很好奇。Debug.Assert是用ConditionalAttribute声明的;正如文档所说,这“[i]表明编译器应该忽略方法调用或属性,除非定义了指定的条件编译符号。”C#编译器对该属性有特定的支持,并在发布构建期间删除Debug.Assert,因此它永远不会成为构建表达式树的一部分。如果您右键单击其中一个Debug.Assert语句,您应该能够转到该定义。VisualStudio将显示从元数据生成的“代码”,您可以在其中看到应用的[Conditional("DEBUG")]属性。因此,只有当DEBUG是#define作为构建的一部分时,才会遵守此代码。调试器上的方法使用伪自定义属性ConditionalAttribute,编译器检测并删除对具有该属性的任何方法的任何调用,除非定义了指定的编译符号(在本例中为DEBUG)。任何人都可以在没有任何输出参数的情况下使用void方法的属性。我不认为Debug.Assert有任何特殊之处;它只使用Conditional属性,以便编译器在检测到“预处理器”定义不存在时将其删除(C#没有预处理器!)。你可以像这样使用它来做同样的事情(只要你定义DEBUG(或者任何你想打开的符号,TRACE是另一个流行的符号):删除Debug.Assert?所有共享的内容,如果对它有用你和你需要了解更多C#学习教程,希望你多多关注——[Conditional("DEBUG"),Conditional("TRACE")]publicvoidDebugOnlyMethod(){Console.WriteLine("Won’tseeme除非定义了DEBUG或TRACE");}本文采集自网络,不代表立场,如涉及侵权,请点击维权联系管理员删除。如需转载,请注明出处来源:
