我有一个相当令人放松的情况,我需要一些永远不会执行但仍需要成为编译输出一部分的代码.虽然我可以提出自己的问题,但我要求社区:什么是最简单,最快速的C#表达式,总是评估为false并且不会生成编译器警告并在最终构建输出中保留所附的代码块?
更新:由于要求解释问题背后的基本原理:Monotouch链接器执行静态代码分析,以便从最终构建中剥离所有未引用的符号,以减小生成的二进制文件的大小.这会产生仅通过反射访问的属性的问题.
我会去简单......
public static bool False() {
return false;
}
public static void Foo() {
if (False()) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
如果你需要说服JIT(内联),那么添加[MethodImpl(MethodImplOptions.NoInlining)]
到False()
[第二次编辑]
在我看来,@ 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)
所以该属性肯定在输出代码中被引用; 因此,这符合要求.