No es una diferencia en el código IL generado.
Esta clase:
class Test1
{
public readonly double Val;
public Test1(bool src)
{
this.Val = src ? 1 : 0;
}
}
Produce este código IL para el constructor:
.class private auto ansi beforefieldinit Demo.Test1
extends [mscorlib]System.Object
{
.field public initonly float64 Val
.method public hidebysig specialname rtspecialname instance void .ctor (
bool src
) cil managed
{
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: brtrue.s IL_000d
IL_000a: ldc.i4.0
IL_000b: br.s IL_000e
IL_000d: ldc.i4.1
IL_000e: conv.r8
IL_000f: stfld float64 Demo.Test1::Val
IL_0014: ret
}
}
Y esta clase:
class Test2
{
public readonly double Val;
public Test2(bool src)
{
this.Val = src ? 1d : 0d;
}
}
Produce este código IL para el constructor:
.class private auto ansi beforefieldinit Demo.Test2
extends [mscorlib]System.Object
{
.field public initonly float64 Val
.method public hidebysig specialname rtspecialname instance void .ctor (
bool src
) cil managed
{
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: brtrue.s IL_0015
IL_000a: ldc.r8 0.0
IL_0013: br.s IL_001e
IL_0015: ldc.r8 1
IL_001e: stfld float64 Demo.Test2::Val
IL_0023: ret
}
}
Como puede ver, en la primera versión tiene que llamar conv.r8para convertir un int en un doble.
Sin embargo: (1) El resultado final es idéntico y (2) el compilador JIT puede traducir ambos al mismo código de máquina.
Así que la respuesta es: Sí, no es una diferencia - pero no uno que tiene que preocuparse.
Personalmente, optaría por la segunda versión, ya que expresa mejor la intención del programador y puede producir un código muy, muy ligeramente más eficiente (dependiendo de lo que haga el compilador JIT).