A vezérlési szerkezetek kapcsán érdemes megjegyezni, hogy a C#, hasonlóan a C és C++ fordítókhoz, fordítás közben átrendezheti a kódot egészen addig, amíg az átrendezett kód viselkedésében azonos a leírttal.
Ez furán hangozhat, szóval inkább nézzünk egy példát. Tételezzük fel, hogy van egy ilyen kódunk:
int x = 0;
x = 10;
A fenti kódban x változó értéke először 0 értéket vesz fel, majd 10-et, de a két művelet között x értékét nem használja fel semmi. Ezért a fordító az alábbi azonosan viselkedő kódot fogja generálni:
int x = 10;
Nézzünk egy másik példát:
int x = 10;
short y = 12;
A fenti kódrészletben y az x változó létrejötte után allokálódik, de memória optimalizáció céljából a futtatókörnyezet dönthet úgy, hogy felcseréli az allokáció sorrendjét, mivel a két művelet között nincs semmi, ami ebbe belezavarna:
short y = 12;
int x = 10;
Ez az utasítás átrendezés a vezérlési szerkezeteket is érinti:
bool test = false;
if (test)
{
Console.WriteLine("Test is true");
}
Console.WriteLine("Test is false");
A fenti kódrészletben a fordítás pillanatában ismert már a test értéke, ami nem módosul. Ebből adódóan a fordító ki tudja hagyni az if ellenőrzést, mivel nem fog előfordulni az az eset, hogy igaz legyen. Ugyanez ez igaz mondjuk egy üres ciklusra is:
for (int i=0; i<100; i++)
{
//üres
}
while (false)
{
//üres
}
A .NET és a C# működéséből adódóan ezen optimalizációk történhetnek a programunk fordításakor, vagy a futtatásakor is, amikor a JIT fordító futtatható kódot készít a programból. A legtöbb esetben ezek az optimalizációk és átrendezések észre sem vehetőek. Azonban többszálú programozás esetén okozhat gondot, de ezzel majd részletesen később foglalkozunk.