C#!条件属性?

Ian*_*oyd 63 c# conditional conditional-compilation

C#有一个没有 Conditional(!Conditional,NotConditional,Conditional(!))属性?


我知道C#有一个Conditional属性:

[Conditional("ShowDebugString")]
public static void ShowDebugString(string s)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

这相当于1:

public static void ShowDebugString(string s)
{
#if ShowDebugString
   ...
#endif
}
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我想要反向行为(你必须明确选择退出):

public static void ShowDebugString(string s)
{
#if !RemoveSDS
   ...
#endif
}
Run Code Online (Sandbox Code Playgroud)

这让我尝试:

[!Conditional("RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

哪个不编译.和:

[Conditional("!RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

哪个不编译.和:

[NotConditional("RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为它只是一厢情愿的想法.

1 不正确,但足够真实.不要让我带回Nitpicker的角落.

Jon*_*eet 55

首先,具有该Conditional属性并不等同于具有#if该方法.考虑:

ShowDebugString(MethodThatTakesAges());
Run Code Online (Sandbox Code Playgroud)

有了真实的行为ConditionalAttribute,MethodThatTakesAges就不会被调用 - 从编译器中删除包括参数评估在内的整个调用.

当然另一点是它依赖于调用者编译时的编译时预处理器符号,而不是方法 :)

但不,我不相信有什么能满足你的需求.我刚刚检查了C#规范部分17.4.2,该部分处理条件方法和条件属性类,并且没有任何内容表明存在任何此类机制.


SLa*_*aks 43

不.

相反,你可以写

#if !ShowDebugString
[Conditional("FALSE")]
#endif
Run Code Online (Sandbox Code Playgroud)

请注意,与[Conditional]此不同,这将取决于程序集中符号的存在,而不是调用者程序集中的符号.

  • 这实际上是最好的解决方案,但是我强烈建议使用长随机散列而不是 FALSE,它可以在某些程序集中设置。 (2认同)

SoL*_*LaR 18

确实,我们不能'不'ConditionalAttribute,但我们可以'不'条件如下所示.

// at the begining of the code before uses
#if DUMMY
#undef NOT_DUMMY
#else
#define NOT_DUMMY
#endif

// somewhere in class
[Conditional("NOT_DUMMY")]
public static void ShowDebugStringNOTDUMMY(string s)
{
  Debug.Print("ShowDebugStringNOTDUMMY");
}


[Conditional("DUMMY")]
public static void ShowDebugStringDUMMY(string s)
{
  Debug.Print("ShowDebugStringDUMMY");
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助您解决问题;)

  • -1很好的尝试,但这并不总是有效,因为这不依赖于调用者的编译时预处理器符号(特别是如果调用者在另一个程序集上,或同一程序集中的另一个模块). (5认同)

Hel*_*iac 13

只需添加我的2美分,三年下线:-) ...我使用一种[Conditional("DEBUG")]方法设置IsDebugMode属性来检查反向.Hacky,但它有效:

private bool _isDebugMode = false;
public bool IsDebugMode
{
    get
    {
        CheckDebugMode();
        return _isDebugMode;
    }
}

[Conditional("DEBUG")]
private void CheckDebugMode()
{
    _isDebugMode = true;
}

private void DisplaySplashScreen()
{
    if (IsDebugMode) return;

    var splashScreenViewModel = new SplashScreenVM(500)
    {
        Header = "MyCompany Deals",
        Title = "Main Menu Test",
        LoadingMessage = "Creating Repositories...",
        VersionString = string.Format("v{0}.{1}.{2}",
            GlobalInfo.Version_Major, GlobalInfo.Version_Minor, GlobalInfo.Version_Build)
    };

    SplashScreenFactory.CreateSplashScreen(splashScreenViewModel);
}
Run Code Online (Sandbox Code Playgroud)

  • 你到底为什么要这么做?为什么不直接使用“#if DEBUG return true;”之类的东西?#否则返回假;#结束`? (4认同)
  • 看看这个关于使用pragma标签与条件属性的优点的深入讨论.在一条评论中解释太多了:http://stackoverflow.com/questions/3788605/if-debug-vs-conditionaldebug (2认同)

Kyl*_*e W 5

#ifndef ShowDebugString
#define RemoveSDS
#endif
Run Code Online (Sandbox Code Playgroud)

?

编辑:更多说明。如果定义了 ShowDebugStringConditional["ShowDebugString"]将被调用。如果 ShowDebugString 未定义,Conditional["RemoveSDS"]将被调用。

  • 不过,这需要在*调用*代码中 - 在需要该功能的每个文件中。IMO,这与要求的有很大不同。 (3认同)