Reputation: 10306
I have a rather esotheric case where I need to have some piece of code that will never execute but which still needs to be part of the compilation output. Although I could come up with my own, I'm asking the community: What is the simplest and fastest C# Expression that always evaluates to false and does not generate a compiler warning and preserves the enclosed block of code in the final build output?
Update: Since explaining the rationale behind the question was requested: The Monotouch linker performs static code analysis in order to strip all unreferenced symbols out of the final build to decrease the size of the generated binaries. This poses a problem with properties only accessed through reflection.
Upvotes: 5
Views: 265
Reputation: 109792
[Second edit]
It seems to me that @Guillaume has suggested the correct answer in comments to the OP, where he suggests that the OP should use custom linking to ensure that the properties in question do not get optimised away: http://docs.xamarin.com/guides/ios/advanced_topics/linker#3.custom-linking
If @Guillaume writes that as an answer, I will remove this edit so that he can rightly get credit.
Original answer:
How about:
if ("".Length > 0)
I checked this code in reflector for a release build (VS2012, .Net 4.5)
void Run()
{
if ("".Length > 0)
{
Console.WriteLine();
}
}
and it produces this 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
}
EDIT: Since there seems to be some debate about whether this will work, let me offer some more evidence.
The goal is to ensure that a property is accessed by the generated code.
Given this C# code:
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; }
}
}
The IL code generated for the Run()
method for a release build is:
.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
}
So the property is definitely being referenced in the output code; thus, this fulfils the requirement.
Upvotes: 5
Reputation: 8502
//Try using `if(1 == 2) {...}`, is that what you want?
Edit: I think below one should not be detected by the compiler:
if(this.GetType().ToString().Equals(string.Empty)
{
......
}
Upvotes: 0
Reputation: 7846
I'd think that testing an object reference == null when you know that it's not null would be the fastest.
Update. Looking at some of the other answers, my guess is that anything that's clearly false on a stand alone is more at risk of being optimised away (if not today, then perhaps in the future) compared to something that you know from the logic of your program must be false. And in terms of the low level opcodes, testing something != 0 is one of the fastest operations that I know.
Upvotes: 2
Reputation: 1063774
I'd go for simple...
public static bool False() {
return false;
}
public static void Foo() {
if (False()) {
...
}
}
If you need to convince JIT too (inlining), then add [MethodImpl(MethodImplOptions.NoInlining)]
to False()
Upvotes: 6
Reputation: 5760
I'm just trying to be creative here (not suggesting anything that has been suggested before), perhaps:
if (new object().GetType() == typeof(string))
I don't think that will be optimized away, but I'm not really in a place where I could test that.
Upvotes: 1