在大型项目中,哪种方法更好,为什么使用:

#if DEBUGpublic void SetPrivateValue(int value){ ... }
#endif

要么

[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }

#1楼

我有一个SOAP WebService扩展,可以使用自定义[TraceExtension]记录网络流量。 我仅将其用于Debug版本,并从Release版本中省略。 使用#if DEBUG包装[TraceExtension]属性,从而将其从Release版本中删除。

#if DEBUG
[TraceExtension]
#endif
[System.Web.Service.Protocols.SoapDocumentMethodAttribute( ... )]
[ more attributes ...]
public DatabaseResponse[] GetDatabaseResponse( ...)
{object[] results = this.Invoke("GetDatabaseResponse",new object[] {... parmeters}};
}#if DEBUG
[TraceExtension]
#endif
public System.IAsyncResult BeginGetDatabaseResponse(...)#if DEBUG
[TraceExtension]
#endif
public DatabaseResponse[] EndGetDatabaseResponse(...)

#2楼

好吧,值得注意的是,它们根本不是同一件事。

如果未定义DEBUG符号,则在第一种情况下,不会调用SetPrivateValue本身...而在第二种情况下,它将存在,但是编译时没有DEBUG符号的任何调用程序都将忽略这些调用。

如果代码及其所有调用者都在同一程序集中,则此区别并不重要-但这意味着在第一种情况下,您需要在调用代码周围包含#if DEBUG

就个人而言,我建议使用第二种方法-但您确实需要清楚地了解它们之间的区别。


#3楼

在第一个示例中,如果未定义DEBUG ,则SetPrivateValue将不存在于构建中;在第二个示例中,如果未定义DEBUG则对SetPrivateValue 调用将不存在于构建中。

在第一个示例中,您还必须使用#if DEBUG包装对SetPrivateValue所有调用。

在第二个示例中,将省略对SetPrivateValue的调用,但是请注意, SetPrivateValue本身仍将被编译。 如果您正在构建库,这将很有用,因此引用您的库的应用程序仍可以使用您的函数(如果满足条件)。

如果要忽略呼叫并节省被呼叫者的空间,可以使用以下两种技术的组合:

[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){#if DEBUG// method body here#endif
}

#4楼

这实际上取决于您要做什么:

  • #if DEBUG :此处的代码在发布时甚至不会到达IL。
  • [Conditional("DEBUG")] :这个代码将到达IL,但是调用来该方法将除非当呼叫者被编译DEBUG设置被省略。

我个人根据情况使用两种:

Conditional(“ DEBUG”)示例:我使用它是为了不必稍后在发行过程中回去编辑我的代码,但是在调试过程中,我想确保自己没有打错任何文字。 尝试在INotifyPropertyChanged东西中使用属性名称时,此函数检查是否正确键入了属性名称。

[Conditional("DEBUG")]
[DebuggerStepThrough]
protected void VerifyPropertyName(String propertyName)
{if (TypeDescriptor.GetProperties(this)[propertyName] == null)Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}",GetType(), propertyName));
}

除非您愿意使用相同的#if DEBUG包装对该函数的每个调用,否则您确实不希望使用#if DEBUG创建一个函数:

#if DEBUGpublic void DoSomething() { }
#endifpublic void Foo(){
#if DEBUGDoSomething(); //This works, but looks FUGLY
#endif}

与:

[Conditional("DEBUG")]
public void DoSomething() { }public void Foo()
{DoSomething(); //Code compiles and is cleaner, DoSomething always//exists, however this is only called during DEBUG.
}

#if DEBUG示例:我在尝试为WCF通信设置不同的绑定时使用它。

#if DEBUGpublic const String ENDPOINT = "Localhost";
#elsepublic const String ENDPOINT = "BasicHttpBinding";
#endif

在第一个示例中,所有代码都存在,但除非打开DEBUG,否则它将被忽略。 在第二个示例中,取决于是否设置了DEBUG,将const ENDPOINT设置为“ Localhost”或“ BasicHttpBinding”。


更新:我正在更新此答案以阐明重要且棘手的问题。 如果选择使用ConditionalAttribute ,请记住,在编译过程中会忽略调用,而在运行时则不会 。 那是:

MyLibrary.dll

[Conditional("DEBUG")]
public void A()
{Console.WriteLine("A");B();
}[Conditional("DEBUG")]
public void B()
{Console.WriteLine("B");
}

当针对发布模式(即没有DEBUG符号)编译该库时,即使包括了对A()的调用,也会永远忽略从A()B()的调用,因为在调用程序集中定义了DEBUG 。


#5楼

假设您的代码还具有#else语句,该语句定义了一个空存根函数,用于解决Jon Skeet的要点之一。 两者之间还有第二个重要区别。

假设#if DEBUGConditional函数存在于主项目可执行文件引用的DLL中。 使用#if ,将对库的编译设置执行条件的评估。 使用Conditional属性,将针对调用程序的编译设置执行条件的评估。


#6楼

我敢肯定,很多人会不同意我的观点,但是作为一名构建专家,我经常听到“但是它在我的机器上可以工作!”,我认为您几乎永远都不要使用。 如果您确实需要测试和调试的东西,请找出一种使可测试性与实际生产代码分开的方法。

在单元测试中使用模拟对场景进行抽象,为要测试的一种场景创建一种版本的事物,但不要将要调试的测试放入要为生产发行版测试和编写的二进制代码中。 这些调试测试只是隐藏了开发人员可能遇到的错误,因此直到该过程的后期才发现它们。


#7楼

这也可能有用:

if (Debugger.IsAttached)
{
...
}

#8楼

通常,您需要在Program.cs中使用它,以便在其中决定对非调试代码运行Debug,而多数情况下则在Windows Services中运行。 因此,我创建了一个只读字段IsDebugMode并在静态构造函数中设置其值,如下所示。

static class Program
{#region Private variablestatic readonly bool IsDebugMode = false;#endregion Private variable#region Constrcutorsstatic Program(){#if DEBUGIsDebugMode = true;#endif}#endregion#region Main/// <summary>/// The main entry point for the application./// </summary>static void Main(string[] args){if (IsDebugMode){MyService myService = new MyService(args);myService.OnDebug();             }else{ServiceBase[] services = new ServiceBase[] { new MyService (args) };services.Run(args);}}#endregion Main
}

#if DEBUG与条件(“ DEBUG”)相关推荐

  1. linux 内核调试信息在哪里,Linux kernel debug技巧----开启DEBUG选项

    Linux kernel debug技巧----开启DEBUG选项 作者:wowo 发布于:2016-11-1 19:39 分类:Linux应用技巧 kernel的source code中有很多使用p ...

  2. Ubuntu 18.04: Debug package with debug symbol

    https://www.hiroom2.com/2018/04/27/ubuntu-1804-dbgsym-en/ 目录 1 Add repository of dbgsym 2 Install db ...

  3. idea debug教程启用Debug模式可以分析定位异常发生的位置

    在现在的开发中,我们经常采用Debug来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟 ...

  4. 【Debug系列】Debug运行正常但是Release出现错误的原因

    目录 一.Debug   和   Release   编译方式的本质区别 二.哪些情况下   Release   版会出错 三.怎样"调试"   Release   版的程序 一. ...

  5. android debug 签名,Android debug签名和release签名

    Android debug签名和release签名 一:Android debug签名 在开发工具下使用debug模式下生成的APK,使用的是开发工具默认的debug签名文件 1.方式一: 通过bui ...

  6. 计算机原理debug,微机原理DEBUG使用.ppt

    微机原理DEBUG使用 DEBUG是一个DOS命令,可用以程序调试,支持直接执行汇编小程序段.1.使用 DEBUG载入要除错的程序时用法如下:(红色的字是你必须输入的,记住每次输入完要按 回车键) H ...

  7. #if DEBUG vs. Conditional(“DEBUG”)

    From StackOverflow: http://stackoverflow.com/questions/3788605/if-debug-vs-conditionaldebug From MSD ...

  8. 在 IDEA 中使用 Debug,真是太厉害了!

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:baojiangzhou http://www.cnblogs.com/chiangcho ...

  9. C# DEBUG 调试信息打印及输出详解

    转载自: http://blog.csdn.net/aaaaatiger/article/details/5583301 1.debug只在[debug模式下才执行](运行按钮后面的下拉框可选) 2. ...

最新文章

  1. Flink从Kafka 0.8中读取多个Topic时的问题
  2. Python基础教程:获取list中指定元素的索引
  3. 软件测试工资高还是运维高,IT行业的6大热门岗位,薪酬都有多高?
  4. Jetty 和tomcat 比较研究初探
  5. mysql5.7 主从数据库操作命令
  6. php mvc框架单例,ZeroPHP: 开发的第一个PHP框架 遵循MVC架构设计。 任重道远。
  7. linux内核中等待队列(wait_event,wake_up...)
  8. 漏洞挖掘 符号执行_漏洞挖掘综述
  9. python -字典生成器
  10. 链塔区块链数据平台周报:新增富豪榜、项目点评、收藏等功能 | 链塔数据
  11. Qt Quick 4小时入门-安晓辉-专题视频课程
  12. 集成灶怎么选品牌(拒绝陷阱避坑指南)
  13. Kylin快速入门系列(6) | 如何通过Zepplin来访问Kylin服务
  14. 无线智能风扇软件端APP设计
  15. 2022-2028年中国基础有机化工原料行业运行动态及前瞻分析报告
  16. 小米6android beam,不只是公交卡!小米手机NFC实用功能盘点
  17. UE4 纯蓝图 WIdget勾选框 互斥
  18. git通过SSH协议提交github(远程仓库)
  19. 死磕k8s之calico-nodeport
  20. 【博弈论】耶鲁大学公开课--博弈论Problem Set 3--Solution

热门文章

  1. 安卓高手之路之ClassLoader(二)
  2. 浅析@Deprecated,调用方法时出现横线划掉样式
  3. 走进STM32世界之Hex程序烧写
  4. android开发之svg全面总结
  5. 瞬间学会使用java中list的retainAll方法
  6. 第三周项目三-输出星号图(3)
  7. jquery的$().each,$.each的区别
  8. Swift Property Wrapper 属性包装器
  9. C# 获取电脑的网络连接状态
  10. MySQL数据库之安装