Рассмотрим следующий код, который использует два слегка различных метода для проверки _instance
и назначения его, когда он еще не установлен.
class InstantiationTest
{
private Object _instance;
public void Method1() {
if(_instance == null) {
_instance = new Object();
}
}
public void Method2() {
_instance = _instance ?? new Object();
}
}
Либо VS, либо Resharper продолжают подчеркивать мои явные проверки нулей и побуждают меня к рефакторингу с использованием оператора объединения нулей.
Мне было интересно, достаточно ли умен компилятор, чтобы обнаружить случай в Method2()
, где _instance
переназначается самому себе (фактически nop ?) И переписывать Method2()
в Method1()
.
Я вижу, что на самом деле это не так:
Test.Method1:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Test._instance
IL_0006: brtrue.s IL_0013
IL_0008: ldarg.0
IL_0009: newobj System.Object..ctor
IL_000E: stfld UserQuery+Test._instance
IL_0013: ret
против:
Test.Method2:
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldfld UserQuery+Test._instance
IL_0007: dup
IL_0008: brtrue.s IL_0010
IL_000A: pop
IL_000B: newobj System.Object..ctor
IL_0010: stfld UserQuery+Test._instance
IL_0015: ret
У меня вопрос почему ?
Это сложно реализовать на уровне компилятора, слишком тривиально, чтобы стоить усилий по реализации, или я чего-то упускаю?