Il existe une différence dans le code IL généré.
Cette classe:
class Test1
{
public readonly double Val;
public Test1(bool src)
{
this.Val = src ? 1 : 0;
}
}
Produit ce code IL pour le constructeur:
.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
}
}
Et cette classe:
class Test2
{
public readonly double Val;
public Test2(bool src)
{
this.Val = src ? 1d : 0d;
}
}
Produit ce code IL pour le constructeur:
.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
}
}
Comme vous pouvez le voir, dans la première version, il doit appeler conv.r8pour convertir un int en double.
Cependant: (1) Le résultat final est identique et (2) le compilateur JIT peut bien traduire les deux dans le même code machine.
La réponse est donc: oui, il y a une différence - mais pas celle dont vous devez vous inquiéter.
Personnellement, j'opterais pour la deuxième version car cela exprime mieux l'intention du programmeur et peut produire un code très très légèrement plus efficace (en fonction de ce que le compilateur JIT obtient).