次のクラス定義を考えてみましょう。
public class MyClass<T>
{
public T t;
public bool? c1(T obj) => obj?.Equals(null);
public bool? c2() => t?.Equals(null);
}
結局のところ、いくつかのメモ:
MyClass<T>
T
タイプに関する制約を課さないため、T
aclass
または astruct
;c2() == c1(t)
常に真でなければなりません。- http://tryroslyn.azurewebsites.net/サイトを使用して、いくつかのコード スニペットをコンパイルし、Roslyn が出力するものを確認しています。
それでは、Roslyn のコンパイル方法を分析してみましょうMyClass<T>
。
1.) c1(T)
ケース:
予想通り、Roslyn コンパイラによって生成されたコードを検証した後、次のことがわかります。
public bool? c1(T obj)
{
return obj != null ? new bool?(obj.Equals(null)) : null;
}
2.) c2()
ケース:
私が期待したのは、c1(T) と同じコードでした。しかし、私が見ているのは次のとおりです。
public unsafe bool? c2()
{
T* arg_33_0 = ref this.t;
T t = default(T);
bool? arg_43_0;
if (t == null)
{
t = this.t;
arg_33_0 = ref t;
if (t == null)
{
arg_43_0 = null;
return arg_43_0;
}
}
arg_43_0 = new bool?(arg_33_0.Equals(null));
return arg_43_0;
}
うわー、なぜこのすべての不要なコードが発行されるのですか? リリース コンパイル モードでは、C1 メソッドのコード サイズが 39 バイトであるのに対し、C2 メソッドのコード サイズは 68 バイトであることがわかります。これは最適化できるものですか?