This is controlled by the compiler. All methods with [Conditional]will continue to be included in MSIL, but will include a string .custom instancethat describes in detail [Conditional]. At compile time, for the compiler’s vocabulary method handler, it then performs semantic analysis and overload resolution, and finds the .custom instanceIL in the method that you placed [Conditional]on. Therefore, it does not compile the call.
So: the compiler compiles the target method, but does not compile the call to this method. Note: the method still exists, and you can still call it reflection. See specification
, . , ; ( ) .
? , ildasm <enter> dlls/exes. [Conditional]. , IL .custom instance, , . .
? , #if. . : ?
class Program
{
static void Main(string[] args)
{
AlwaysEmit();
DebugEmit();
VerboseEmit();
}
public static void AlwaysEmit()
{
Console.WriteLine("Beam me up");
}
[Conditional("DEBUG")]
public static void DebugEmit()
{
Console.WriteLine("Kirk out");
}
[Conditional("VERBOSE")]
public static void VerboseEmit()
{
Console.WriteLine("Say that again?");
}
}
MSIL VerboseEmit , Main:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
IL_0000: nop
IL_0001: call void RateScope.SdrApi.UploaderConsoleApp.Program::AlwaysEmit()
IL_0006: nop
IL_0007: call void RateScope.SdrApi.UploaderConsoleApp.Program::DebugEmit()
IL_000c: nop
IL_000d: ret
}
...
.method public hidebysig static void VerboseEmit() cil managed
{
.custom instance void [mscorlib]System.Diagnostics.ConditionalAttribute::.ctor(string)
= ( 01 00 07 56 45 52 42 4F 53 45 00 00 )
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Say that again\?"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
}
. MSIL ( Emit):
static void Main(string[] args)
{
int callCount = 0;
AlwaysEmit(++callCount);
VerboseEmit(++callCount);
DebugEmit(++callCount);
Console.WriteLine("Call count = " + callCount);
Console.ReadLine();
}