web-dev-qa-db-ja.com

単純なC#Noopステートメント

メソッドの実装を必要としない、C#の単純なNoopステートメントとは何ですか? (ただし、インライン/ラムダメソッドは問題ありません。)

私の現在の使用例:try-catchのcatchブロックを占有したいので、デバッグ中にステップインして例外を検査できます。
とにかく例外を処理/ログに記録する必要があることは承知していますが、それがこの演習のポイントではありません。

42
Protector one

本当に何もしない場合、これは何もしない名前のないアクションを定義し、それを呼び出して何も起こさないようにします。

((Action)(() => { }))();
67
AHM

C#の標準の空のステートメント/ noop操作は

;

のように:

if (true)
    ;

関連ドキュメント

これは具体的にはユースケースに対応し(;行にブレークポイントを置くか、それ以外の方法でステップに進む)、最小限であり、この目的のためだけに環境によって直接サポートされます(したがって、複雑なことをしている場合でも、コンパイルされたソースを見るのと同じように、コンパイラ/オプティマイザ/などから心配する追加のノイズなどはありません-そして、警告を表示するという追加の利点がありますデバッグが完了したら、コードからそれを削除します/本番環境にプッシュします

55
blueberryfields

メソッドに割り込む場合は、ブレークポイントをハードコーディングできます。

_System.Diagnostics.Debugger.Break();
_

または、リリースモードでコンパイルしない場合、次の行はILを発行し、中断できます。

_var a = 1;
_

マシンに固有のDebug.Break()を作成することもできます。

_[Conditional("DEBUG")]
[Obsolete("Please remove me before checkin.")]
public static void Break()
{
    #IF DEBUG
    if (Dns.GetHostName() == "PROTECTORONE")
        Debugger.Break();
    #ENDIF
}
_

[Conditional("DEBUG")]があるため、RELEASEのビルド中に呼び出しサイトでそのメソッドが呼び出されないことに注意してください。

16

何もしない関数を書くことができます。

public static void Noop()
{
}
8
Pratik Deoghare

あなたはただ書くことができます:

catch {
    ;
}

セミコロンが1つある空のステートメントはC#NOOPです。

7
Sefe

C#での標準の空のステートメント/ noop操作は、if (true) ;と同様に_;_です。
-ブルーベリーフィールズ

Butifステートメントのブランチとしてその標準の_;_を使用すると、MS Visual Studio 2010で警告が表示されます:「空のステートメントが誤っている可能性があります」。 (CS0642に警告しますが、VS2010はそれを教えたり、警告の実際のヘルプにリンクしたりしません。)

悪い、 MSDN C#言語仕様では、空のステートメントをifステートメントは、警告CS0642「起こり得る誤った空のステートメント」を引き起こします。 (「不正な形式」である可能性があるため、あいまいである可能性があるため警告します。)

さらに悪いことに VS2010は個々の警告を適切に抑制する方法を提供していないようです。行の前に_#pragma warning disable CS0642_を挿入し、[オプションで] _#pragma warning disable CS0642_を挿入する必要があります。私には、これは警告よりも醜いです。 _{ }_の代わりに_;_を使用したほうがよいでしょう。 (私は少し醜いオーバーライドを使用するかもしれません。)

その警告を取り除くために、「空のステートメント」の代わりとなるものが欲しかったので、「C#no-op」をここで探しました。チェックポイントは必要ありません。 「空のステートメント」のように曖昧ではないことをしたいだけです。

代替手段は、その他の警告を引き起こしてはなりません。 _int u;_は、「変数 'u'が宣言されていますが、使用されていません」という警告を引き起こすため、無効です。 _int u = 0;_は、「変数 'u'が割り当てられていますが、その値は使用されていません」という警告を引き起こすため、問題があります。

_noop;_(または類似の)が明確な空のステートメント(マクロ定義ではない)として追加された場合、それはすばらしいことです。

noop();(または類似の)が空の本体を持つ関数である場合(コンパイラーがインライン化すると完全に消えることがあります)、それはほぼ素晴らしいことです。

分岐が1つのステートメントだけの場合、周囲の_{_および_}_ LINESは必要ないため、コードを垂直方向に引き伸ばして読みにくくするため、省略します。言語の矛盾は、ZEROステートメントを囲むときに、周囲の_{_および_}_ LINESを省略できないことです。 2つの行を同じ行で_{ }_に圧縮できますが、これには一貫性がありません。行の_;_は最も近い解決策であると思います。「悪い形」という理由から[言及されていない]という理由で警告が出されることはないはずです。警告CS0642はデフォルトでオフになっているはずです。次のコードはそのまま受け入れられるはずです。

_if (condition1)
  action1;
else if (condition2)
  ;  // (do nothing)
else if (condition3)
  action3;
else if (condition4)
  ;  // (do nothing)
else if (condition5)
  action5;
else
  action99;
_

(まだ「コメントするのに50の評判」がなかったので、コメントとしてこれを書き込むことができないことを嘆きました。2Kバイトでコメントできるようになったので、1.5Kバイトのコメントには長すぎるため、ここに残っています。 。)

6
A876

どうですか:

GC.KeepAlive(e);

ここで、eは例外変数ですか?

(catch宣言自体にブレークポイントを設定しようとしたことはありません。このため、正確にこれを行うことができるように感じますought。しかし、それが機能するかどうかは別の問題です。)

または、もう少し不可解ですが、System.LINQのusingディレクティブがすでにあると仮定します。

"".AsEnumerable();
6
Jon Skeet

質問に直接答える回答に加えて。


単にブレークしたい場合は、いつでも開始点にブレークポイントを置くことができます{または終了} of catchブロック。

4
George Duckett

なぜこれを過剰設計するのですか?

var x = 0;

うまくいきます:)

4
Todd Menier

私はこれが古い質問であることを知っており、技術的には、この回答は質問者の使用例とは関係ありません。ただし、CILにはNOOP命令、つまりnopがあります。実験として、次のCILアプリケーションを使用します。

.Assembly extern mscorlib {}

.Assembly Test
{
    .ver 1:0:1:0
}
.module test.exe

.method static void main() cil managed
{
    .maxstack 1
    .entrypoint

    nop
    nop
    nop
    nop

    ret
}

アプリケーションをコンパイルし、ILSpyなどのツールを使用してC#に逆コンパイルすると、main()メソッドの内容は次のようになります。

static void main()
{
}

ご覧のとおり、何もありません。ただし、CILコンパイラーがこれらのnopステートメントを最適化していないことを確認したい場合は、ILSpyで逆コンパイルされたILコードでアプリケーションを表示できます。これは、メインメソッドで確認できます。

.method static privatescope 
    void main$PST06000001 () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 5 (0x5)
    .maxstack 1
    .entrypoint

    IL_0000: nop
    IL_0001: nop
    IL_0002: nop
    IL_0003: nop
    IL_0004: ret
} // end of method '<Module>'::main

CILは確かにnop命令をアセンブリにコンパイルしています。 C#にはこの命令の実装がないため、これらのnopコマンドは逆アセンブルされたC#コード内には表示されません。

Reflectorのライセンスはありませんが、これらのバイナリをReflectorで逆コンパイルすると、C#でも同様の出力が得られると思います。

4
RLH

まあCのようにC#のNOPが存在し、';'とその正しい定義は "空のステートメント"ですが、意図する使用法では、ブレークポイントを閉じキャッチブラケットに入れるのに十分です...キープアライブを実行する必要はありません。メソッド内のオブジェクト参照の存続期間は、デバッガーがアタッチされたときにメソッドの最後まで延長されるためです。だからあなたは単に書く必要があります

catch(Exception exception)
{
}

ブレークポイントを閉じ括弧に置き、例外の内容を確認します。

3
Felice Pollano

リリース(最適化)ビルドをデバッグしようとしていますか?参照されていない変数と空のブロックを削除するのは通常、オプティマイザです。

2つのソリューション:

  • デバッグビルドでデバッグします。
  • ローカルツールウィンドウで、catch自体にブレークポイントを設定し、デバッガーによって作成された$exception(進行中の例外を参照するために作成)を使用します。
2
Richard

これは@AHMの回答への追加です。私はデバッグのためにNOOPを実行する簡単な方法が必要だったためです(AB PLC CompactLogixと通信して、C++ライブラリDLL = C#でインポート)。

ワンライナーをとった

((Action)(() => { }))();

noop.snippetという名前のスニペットに入れて、My Code Snippetsという名前のフォルダーに入れます。
ツール->コードスニペットマネージャー->場所)ORコード(Ctrl + K 、Ctrl + B

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.Microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>noop</Title>
            <Shortcut>noop</Shortcut>
            <Description>Code snippet to inject an Assembly (x86) equivalent of the NOOP command into the code's disassembly.</Description>
            <Author>Jay Whaley</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Code Language="csharp">
            <![CDATA[// Forces a psuedo NOOP in disassembly
                ((Action)(() => { }))();
            $end$]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

これは、低レベルの通信が混乱し、これが一般的なデバッグ戦術である必要がある場合に、これをすばやく使用できるショートカットにするのに役立ちます。生成される実際のアセンブリは次のとおりですが、 [/// =)を使用する方法に関するいくつかの投稿の実際のアセンブリをインラインでC#に挿入します。

Disassembly generated from invoking a nameless action

1
Jay Whaley

信頼できるソリューション

try
{
   blablablablaStatemnt();
}
catch(Exception ex)
{
    #IF DEBUG
       Debugger.Break();
    #END IF
}

これと同じくらい簡単です!

さもないと

ブレークポイント

非常に便利です。

0