web-dev-qa-db-ja.com

C#!条件付き属性?

C#にはnotConditional(_!Conditional_、NotConditionalConditional(!)がありますか)属性?


私はC#に Conditional属性 があることを知っています

_[Conditional("ShowDebugString")]
public static void ShowDebugString(string s)
{
   ...
}
_

同等です1 に:

_public static void ShowDebugString(string s)
{
#if ShowDebugString
   ...
#endif
}
_

しかし、この場合、inverse動作が必要です(具体的にはopt out):

_public static void ShowDebugString(string s)
{
#if !RemoveSDS
   ...
#endif
}
_

それは私を試してみることにつながります:

_[!Conditional("RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
_

コンパイルしません。そして:

_[Conditional("!RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
_

コンパイルしません。そして:

_[NotConditional("RemoveSDS")]
public static void ShowDebugString(string s)
{
   ...
}
_

希望的観測のみであるため、コンパイルされません。

1 真実ではありませんが、十分真実です。ニトピッカーのコーナーを戻さないでください。

62
Ian Boyd

まず、Conditional属性を持つことはnotメソッドではなく#ifを持つことと同等です。考慮してください:

ShowDebugString(MethodThatTakesAges());

ConditionalAttributeの実際の動作では、MethodThatTakesAgesは呼び出されません-呼び出し全体引数の評価を含むはコンパイラから削除されます。

もちろん、他のポイントは、callerではなくcallerのコンパイル時のコンパイル時プリプロセッサシンボルに依存することです。

しかし、いや、私はあなたがここで望んでいることをする何かがあるとは思わない。 条件付きメソッドと条件付き属性クラスを扱うC#仕様セクション を確認しましたが、そのようなメカニズムがあることを示唆するものは何もありません。

54
Jon Skeet

いや。

代わりに、書くことができます

#if !ShowDebugString
[Conditional("FALSE")]
#endif

[Conditional]とは異なり、これは、呼び出し元のアセンブリではなく、アセンブリ内のシンボルの存在によって決定されることに注意してください。

43
SLaks

条件属性を「否定」することはできませんが、以下に示すように条件を「否定」することはできません。

// 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");
}

これがあなたの問題の解決に役立つことを願っています;)

18
SoLaR

ちょうど2セントを追加して、3年後に:-) ... [Conditional("DEBUG")]メソッドを使用してIsDebugModeプロパティを設定し、逆をチェックします。ハックが、それは動作します:

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);
}
13
Heliac
#ifndef ShowDebugString
#define RemoveSDS
#endif

編集:より明確にするため。 ShowDebugStringが定義されている場合Conditional["ShowDebugString"]が呼び出されます。 ShowDebugStringが定義されていない場合、Conditional["RemoveSDS"]が呼び出されます。

4
Kyle W

NETフレームワーク標準ライブラリの注釈付きリファレンスには何も記載されていません。だから、あなたはあなた自身を転がさなければならないのではないかと心配しています!

0
Roy Dictus