Ну, это полностью зависит от языка и компилятора. Использование компилятора C #, поставляемого с фреймворком, не имеет значения, так как вывод IL одинаков. Вот пример рутины:
static void Main(string[] args)
{
// Create the instance.
MyClass instance = new MyClass();
if (null == instance)
{
}
if (instance == null)
{
}
}
IL для первого сравнения выглядит следующим образом:
L_0007: ldnull
L_0008: ldloc.0
L_0009: ceq
L_000b: ldc.i4.0
L_000c: ceq
L_000e: stloc.1
L_000f: ldloc.1
L_0010: brtrue.s L_0014
L_0012: nop
L_0013: nop
И второе:
L_0014: ldloc.0
L_0015: ldnull
L_0016: ceq
L_0018: ldc.i4.0
L_0019: ceq
L_001b: stloc.1
L_001c: ldloc.1
L_001d: brtrue.s L_0021
L_001f: nop
L_0020: nop
Как видите, выходные данные практически идентичны, за исключением порядка элементов в стеке. Операции такие же.
Как упоминалось ранее, это реликвия из старых дней C, где все, что имеет значение 0, оценивается как ложное, и если вы пропустили знак равенства, присвоение было оценено как условное.
Вам не нужно беспокоиться об этом в .NET, так как условные выражения будут принимать только логические значения, но если вы сравниваете с истиной / ложью, возможно, все же лучше использовать кодирование, чтобы сначала ставить буквальное значение, так чтобы случайно не оценить задание.