简单的C#Noop声明

时间:2011-08-03 10:07:20

标签: c# noop

C#中的简单Noop语句是什么,不需要实现方法? (但内联/ Lambda方法没问题。)

我当前的用例:我想占用try-catch的catch-block,所以我可以在调试时进入它并检查异常。
我知道无论如何我应该处理/记录异常,但这不是这个练习的重点。

15 个答案:

答案 0 :(得分:60)

如果你真的想要noop,那么这就定义了一个无法执行任何操作的无名动作,然后调用它,不会发生任何事情:

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

答案 1 :(得分:49)

c#中的标准空语句/ noop操作是

;

如:

if (true)
    ;

relevant documentation

这专门针对您的用例(只是在;行上放置一个断点,或以其他方式步骤),是最小的,并且仅为此目的直接受环境支持(所以即使你是做复杂的事情,比如查看已编译的源代码,你不会有任何额外的噪音/等等......担心编译器/优化器/等......) - 并且还有额外的好处,就是发出警告,如当您完成调试/推送到生产时,提醒您将其从代码中清除

答案 2 :(得分:16)

如果你想进入方法,可以对断点进行硬编码:

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构建期间不会在调用网站中调用该方法。

答案 3 :(得分:7)

你可以写一个什么都不做的功能。

public static void Noop()
{
}

答案 4 :(得分:7)

你可以写:

catch {
    ;
}

带有单个分号的空语句是C#NOOP。

答案 5 :(得分:5)

怎么样:

GC.KeepAlive(e);

其中e是异常变量?

(我没有尝试在捕获声明本身上设置一个断点。感觉就像你应该能够做到这一点,正是因为这个原因。但它是否有效是另一件事。)

或者更隐蔽,假设您已经有System.LINQ的使用指令:

"".AsEnumerable();

答案 6 :(得分:4)

除了直接回答问题的答案。


如果您只想打破,那么您可以始终将断点放在{块的开头}或关闭catch上。

答案 7 :(得分:4)

为什么要过度设计这个?

var x = 0;

工作正常:))

答案 8 :(得分:4)

  

C#中的标准空语句/ noop操作与;中的if (true) ;一样        - blueberryfields

但是使用该标准;作为if语句的分支使得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();(或类似)是一个空体的函数(当编译器内联时它可以完全消失),那几乎就会很棒。

当分支只有一个语句时,我经常省略周围的{} LINES,因为它们不需要它们并且它们会垂直拉伸代码,使其更难阅读。语言的不一致是当我们围绕ZERO语句时,我不能忽略周围的{} LINES。我可以将两行压缩到同一行的{ },但这是不一致的。我认为;在一条线上是最好的解决方案,它不应该在[未说明的]“坏形式”的基础上引起警告。我认为警告CS0642应该默认为OFF。我认为以下代码应该是可以接受的:

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字节太长了,所以它住在这里。)

答案 9 :(得分:3)

C#中的NOP存在,就像在C中一样';'并且它的正确定义是“空语句”,但是对于你想要的用法,应该把它放在关闭捕获支架中的断点... 不需要保持活动,因为在附加调试器时,方法中对象引用的生命周期会扩展到方法的末尾。所以你只需要写

catch(Exception exception)
{
}

并将断点放在右括号上并查看异常内容。

答案 10 :(得分:3)

我知道这是一个老问题,从技术上讲,这个答案与提问者的用例无关。但是,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代码查看我们的应用程序,这就是我们对main方法的看法: / p>

.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#输出。

答案 11 :(得分:2)

您是否尝试调试发布(优化)版本?通常是优化器可以删除未引用的变量和空块。

两种解决方案:

  • 在调试版本中进行调试。
  • catch本身上设置一个断点,然后使用调试器创建的$exception来引用飞行中的异常 - 在“本地”工具窗口中。

答案 12 :(得分:1)

这是@AHM答案的补充,因为我想要一种简便的方法来进行NOOP以便进行调试(与AB PLC CompactLogix进行通信,并且由于C#中C ++库DLL的导入而遇到了仅在反汇编中真正可见的错误)。

我拿了单线纸

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

并将其放入名为 noop.snippet 的代码段中,然后将其放置在名为“我的代码段”的文件夹中。
工具->代码段管理器->位置)或和弦( 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>

在低级通信变得混乱的情况下,这有助于使其成为快速使用的快捷方式,并要求这是一种常见的调试策略。生成的实际程序集如下,但有some posts about how to use actual assembly inline in C#.

Disassembly generated from invoking a nameless action

答案 13 :(得分:0)

可靠的解决方案

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

就这么简单!

否则

断点

非常有用;

答案 14 :(得分:-1)

我非常喜欢这个,因为它会让遇到它的人感到困惑:

catch (SomeException e)
{
    lock(e);
}