最简单的最快的C#表达式,总是计算为false并且不会生成编译器警告

Oli*_*old 5 c# xamarin.ios

我有一个相当令人放松的情况,我需要一些永远不会执行但仍需要成为编译输出一部分的代码.虽然我可以提出自己的问题,但我要求社区:什么是最简单,最快速的C#表达式,总是评估为false并且不会生成编译器警告并在最终构建输出中保留所附的代码块?

更新:由于要求解释问题背后的基本原理:Monotouch链接器执行静态代码分析,以便从最终构建中剥离所有未引用的符号,以减小生成的二进制文件的大小.这会产生仅通过反射访问的属性的问题.

Mar*_*ell 6

我会去简单......

public static bool False() {
    return false;
}
public static void Foo() {
    if (False()) {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你需要说服JIT(内联),那么添加[MethodImpl(MethodImplOptions.NoInlining)]False()

  • @OliverWeichhold很确定,是的.随意检查.如果你想**铸铁** - 调用`virtual`属性/方法.编译器不能删除它,因为子类可以做一些不同的事情. (2认同)

Mat*_*son 5

[第二次编辑]

在我看来,@ Guillaume在对OP的评论中提出了正确的答案,他建议OP应该使用自定义链接来确保所讨论的属性不会被优化掉:http://docs.xamarin.com /guides/ios/advanced_topics/linker#3.custom-linking

如果@Guillaume将其作为答案写入,我将删除此编辑,以便他可以正确地获得信用.


原始答案:

怎么样:

if ("".Length > 0)
Run Code Online (Sandbox Code Playgroud)

我在反射器中检查了此代码以发布版本(VS2012,.Net 4.5)

void Run()
{
    if ("".Length > 0)
    {
        Console.WriteLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

它产生这个IL:

.method private hidebysig instance void Run() cil managed
{
    .maxstack 8
    L_0000: ldstr ""
    L_0005: callvirt instance int32 [mscorlib]System.String::get_Length()
    L_000a: ldc.i4.0 
    L_000b: ble L_0015
    L_0010: call void [mscorlib]System.Console::WriteLine()
    L_0015: ret 
}
Run Code Online (Sandbox Code Playgroud)

编辑:由于似乎有一些关于这是否有效的争论,让我提供一些更多的证据.

目标是确保生成的代码访问属性.

鉴于此C#代码:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            new Program().Run();
        }

        void Run()
        {
            if ("".Length > 0)
            {
                Test t = new Test();
                Trace.WriteLine(t.Property); // Make sure we use the property.
            }
        }
    }

    internal class Test
    {
        public int Property { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Run()为发布版本的方法生成的IL代码是:

.method private hidebysig instance void Run() cil managed
{
    .maxstack 5
    .locals init (
        [0] class ConsoleApplication1.Test t)
    L_0000: ldstr ""
    L_0005: callvirt instance int32 [mscorlib]System.String::get_Length()
    L_000a: ldc.i4.0 
    L_000b: ble L_0026
    L_0010: newobj instance void ConsoleApplication1.Test::.ctor()
    L_0015: stloc.0 
    L_0016: ldloc.0 
    L_0017: callvirt instance int32 ConsoleApplication1.Test::get_Property()
    L_001c: box int32
    L_0021: call void [System]System.Diagnostics.Trace::WriteLine(object)
    L_0026: ret 
}
Run Code Online (Sandbox Code Playgroud)

所以该属性肯定在输出代码中被引用; 因此,这符合要求.

  • @WouterHuysentruit想打赌?:) (2认同)