#如果DEBUG与条件(QUOT; DEBUG") [英] #if DEBUG vs. Conditional("DEBUG")

查看:118
本文介绍了#如果DEBUG与条件(QUOT; DEBUG")的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

哪个更好用,为什么,在一个大型项目:

 #如果DEBUG
    公共无效SetPrivateValue(int值)
    {...}
#万一

  [System.Diagnostics.Conditional(DEBUG)]
公共无效SetPrivateValue(int值)
{...}


解决方案

这真的取决于你要什么:


  • #如果DEBUG :对发布在这里code甚至不会达到IL

  • [条件(DEBUG)] :这code将达到IL,但是的通话的的方法将被省略除非当来电被编译DEBUG设置。

我个人使用都根据具体情况:

条件(调试)例如:我用这个,这样我就不必回去和释放过程中稍后编辑我的code,但在调试过程中我想肯定我没有做任何错别字。这是我正确地输入属性名称,功能检查时,想在我INotifyPropertyChanged的东西来使用它。

  [条件(DEBUG)]
[DebuggerStepThrough]
保护无效VerifyPropertyName(字符串propertyName的)
{
    如果(TypeDescriptor.GetProperties(本)[propertyName的] == NULL)
        Debug.Fail(的String.Format(无效的属性名称类型:{0},名称:{1},
            的GetType(),propertyName的));
}

您真的不希望创建使用函数#如果DEBUG 除非你愿意来包装每次调用该函数具有相同 #如果DEBUG

 #如果DEBUG
    公共无效DoSomething的(){}
#万一    公共无效美孚()
    {
#如果DEBUG
        做一点事(); //这工作,但看起来是fugly
#万一
    }

  [条件(DEBUG)]
公共无效DoSomething的(){}公共无效美孚()
{
    做一点事(); // code编译和更干净,总的DoSomething
                   //存在,不过这是在调试期间只调用。
}


#如果DEBUG例如:我试图安装不同的绑定WCF通信时使用此

 #如果DEBUG
        公共常量字符串终点=本地主机;
#其他
        公共常量字符串终点=basicHttpBinding的;
#万一

在第一个例子中,code都存在,但只是忽略,除非DEBUG为上。在第二个例子中,const的终点是取决于如果DEBUG设置或不设置为本地主机或basicHttpBinding的。


更新:因为这个答案是最高的投票问题的答案,我更新这个答案澄清一个重要而棘手的问题。如果您选择使用 ConditionalAttribute ,记住,调用在编译过程中省略,和不是运行即可。这就是:

MyLibrary.dll

  [条件(DEBUG)]
公共无效A()
{
    Console.WriteLine(A);
    B();
}[条件(DEBUG)]
公共无效B()
{
    Console.WriteLine(B);
}

在该库对释放模式(即没有调试符号)编译的,它会永远有呼叫 B()从内部 A ()省略,即使到呼叫 A()被包括在内,因为DEBUG在调用程序集定义。

Which is better to use, and why, on a large project:

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

or

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

解决方案

It really depends on what you're going for:

  • #if DEBUG: The code in here won't even reach the IL on release.
  • [Conditional("DEBUG")]: This code will reach the IL, however calls to the method will be omitted unless DEBUG is set when the caller is compiled.

Personally I use both depending on the situation:

Conditional("DEBUG") Example: I use this so that I don't have to go back and edit my code later during release, but during debugging I want to be sure I didn't make any typos. This function checks that I type a property name correctly when trying to use it in my INotifyPropertyChanged stuff.

[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));
}

You really don't want to create a function using #if DEBUG unless you are willing to wrap every call to that function with the same #if DEBUG:

#if DEBUG
    public void DoSomething() { }
#endif

    public void Foo()
    {
#if DEBUG
        DoSomething(); //This works, but looks FUGLY
#endif
    }

versus:

[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 example: I use this when trying to setup different bindings for WCF communication.

#if DEBUG
        public const String ENDPOINT = "Localhost";
#else
        public const String ENDPOINT = "BasicHttpBinding";
#endif

In the first example, the code all exists, but is just ignored unless DEBUG is on. In the second example, the const ENDPOINT is set to "Localhost" or "BasicHttpBinding" depending on if DEBUG is set or not.


Update: Because this answer is the highest voted answer to the question, I am updating this answer to clarify an important and tricky point. If you choose to use the ConditionalAttribute, keep in mind that calls are omitted during compilation, and not runtime. That is:

MyLibrary.dll

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

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

When the library is compiled against release mode (i.e. no DEBUG symbol), it will forever have the call to B() from within A() omitted, even if a call to A() is included because DEBUG is defined in the calling assembly.

这篇关于#如果DEBUG与条件(QUOT; DEBUG")的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆