简单的C#Noop声明

Pro*_*one 39 c# no-op

C#中的简单Noop语句是什么,不需要实现方法?(但内联/ Lambda方法还可以.)

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

AHM*_*AHM 62

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

((Action)(() => { }))();
Run Code Online (Sandbox Code Playgroud)

  • 答案听起来像是道格拉斯·亚当斯写的。 (3认同)

blu*_*lds 54

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

;
Run Code Online (Sandbox Code Playgroud)

如:

if (true)
    ;
Run Code Online (Sandbox Code Playgroud)

(相关文件)

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

  • IMO这个应该被标记为答案. (4认同)
  • IMO也是正确的答案。我会添加诸如“ // NOOP”之类的注释,以使之知道是故意的。 (2认同)

Jon*_*son 16

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

System.Diagnostics.Debugger.Break();
Run Code Online (Sandbox Code Playgroud)

或者,如果您不在发布模式下编译,则以下行将发出IL,您可以将其打破:

var a = 1;
Run Code Online (Sandbox Code Playgroud)

您还可以编写一个特定于您的机器的Debug.Break():

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

请注意,因为[Conditional("DEBUG")]在RELEASE构建期间不会在调用站点中调用该方法.

  • @Protector one - 现在它甚至会警告您在构建过程中正在使用;并且它不会进入 RELEASE 构建(C# 编译器不会调用该方法)。 (2认同)

Pra*_*are 7

你可以编写一个什么都不做的函数.

public static void Noop()
{
}
Run Code Online (Sandbox Code Playgroud)

  • @Protector"无方法"规则是任意的,我只会忽略它 (6认同)
  • @David:这不是任意的,因为它是问题的先决条件之一.人们可以质疑它是否是一个*明智的先决条件,但如果没有先决条件,我认为这个问题甚至不存在.所以答案应该*反对先决条件*或*给出一个与之相匹配的答案 - 而不是仅仅违反先决条件,就像没有说明一样. (2认同)

Sef*_*efe 7

你可以写:

catch {
    ;
}
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*eet 6

怎么样:

GC.KeepAlive(e);
Run Code Online (Sandbox Code Playgroud)

e异常变量在哪里?

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

或者更隐秘,假设你已经有了一个using指令System.LINQ:

"".AsEnumerable();
Run Code Online (Sandbox Code Playgroud)

  • @Protector one:值类型有多少例外? (5认同)

Geo*_*ett 6

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


如果您只是想中断,那么您可以随时将断点放在块的开头{或结尾处。}catch


Ant*_*yVO 6

在考虑了各种选项之后,我认为一对空括号和简洁的注释是最干净的。没有额外的代码,自记录,并且比单个分号明显得多。

{/* Noop */}
Run Code Online (Sandbox Code Playgroud)

例如

if (String.IsNullOrEmpty(value))
    {/* Noop */}
else if (Data.ContainsKey(key))
Run Code Online (Sandbox Code Playgroud)


Who*_*asy 6

很多很棒的解决方案!我的去处是:

_ = "";
Run Code Online (Sandbox Code Playgroud)

当您想要确认有返回值,但您不想要或不需要它时,使用 _。它可以让编译器安静下来,避免告诉您没有获得返回值。


RLH*_*RLH 5

我知道这是一个老问题,从技术上讲,这个答案与提问者的用例无关。但是,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
}
Run Code Online (Sandbox Code Playgroud)

如果编译应用程序,并使用ILSpy之类的工具将其反编译为C#,则这是main()方法的内容:

static void main()
{
}
Run Code Online (Sandbox Code Playgroud)

如您所见,那里什么都没有。但是,如果我们想验证 CIL 编译器没有优化这些nop语句,我们可以在 ILSpy 中查看我们的应用程序在反编译的 IL 代码中,这就是我们看到的 main 方法:

.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
Run Code Online (Sandbox Code Playgroud)

CIL 肯定是将nop指令编译到程序集中。由于 C# 没有实现此指令,因此这些nop命令未显示在反汇编的 C# 代码中。

我没有 Reflector 的许可证,但我想如果你用 Reflector 反编译这些二进制文件,你会得到类似的 C# 输出。


A87*_*876 5

C#中的标准空语句/ noop操作;与中的相同if (true) ;
-蓝莓田

但是使用该标准;作为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;
Run Code Online (Sandbox Code Playgroud)

(我很遗憾无法将其写为评论,因为我还没有“拥有50条信誉来发表评论。”现在,我可以以2K字节进行评论,对于1.5K字节的评论来说太长了,所以它留在这里)