Предположим, у меня есть обычное перечисление флагов:
Код: Выделить всё
[Flags]
public enum MyFlags
{
None = 0,
A = 0x01,
B = 0x02,
C = 0x04,
D = 0x08,
}
Код: Выделить всё
public class C {
public void M1() {
MyFlags flags = MyFlags.A;
flags |= MyFlags.B | MyFlags.C | MyFlags.D;
Console.WriteLine((int)flags);
}
public void M2() {
MyFlags flags = MyFlags.A;
flags |= MyFlags.B;
flags|= MyFlags.C;
flags|= MyFlags.D;
Console.WriteLine((int)flags);
}
}
Что меня удивляет, так это сгенерированный C# как Release с использованием SharpLab :
Код: Выделить всё
public class C
{
public void M1()
{
Console.WriteLine(1 | 0xE);
}
public void M2()
{
Console.WriteLine(7 | 8);
}
}
Зачем оставлять последнюю операцию ИЛИ вместо объединения с предыдущей?< /p>
Это еще не все. Если я проверю IL (все еще Release), результат станет хуже:
Код: Выделить всё
// Methods
.method public hidebysig
instance void M1 () cil managed
{
// Method begins at RVA 0x2050
// Code size 10 (0xa)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: ldc.i4.s 14
IL_0003: or
IL_0004: call void [System.Console]System.Console::WriteLine(int32)
IL_0009: ret
} // end of method C::M1
.method public hidebysig
instance void M2 () cil managed
{
// Method begins at RVA 0x205b
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: ldc.i4.2
IL_0002: or
IL_0003: ldc.i4.4
IL_0004: or
IL_0005: ldc.i4.8
IL_0006: or
IL_0007: call void [System.Console]System.Console::WriteLine(int32)
IL_000c: ret
} // end of method C::M2
Код: Выделить всё
C.M1()
L0000: mov ecx, 0xf
L0005: call dword ptr [0x207a72b8]
L000b: ret
C.M2()
L0000: mov ecx, 0xf
L0005: call dword ptr [0x207a72b8]
L000b: ret
Подробнее здесь: https://stackoverflow.com/questions/792 ... ion-result
Мобильная версия