私は以前にこれをお見せしたと思いますが、私はここの楽しみが好きです-これは追跡するためにデバッグが必要でした!(元のコードは明らかにより複雑で微妙でした...)
static void Foo<T>() where T : new()
{
T t = new T();
Console.WriteLine(t.ToString()); // works fine
Console.WriteLine(t.GetHashCode()); // works fine
Console.WriteLine(t.Equals(t)); // works fine
// so it looks like an object and smells like an object...
// but this throws a NullReferenceException...
Console.WriteLine(t.GetType());
}
それで、Tは何でしたか...
回答:任意Nullable<T>
-などint?
。取得できないGetType()を除いて、すべてのメソッドがオーバーライドされます。したがって、オブジェクトにキャスト(ボックス化)され(したがってnullに)、object.GetType()...を呼び出してnullを呼び出します;-p
アップデート:プロット濃く... Ayende Rahienが投げた彼のブログ上で同様の課題を、しかしとwhere T : class, new()
:
private static void Main() {
CanThisHappen<MyFunnyType>();
}
public static void CanThisHappen<T>() where T : class, new() {
var instance = new T(); // new() on a ref-type; should be non-null, then
Debug.Assert(instance != null, "How did we break the CLR?");
}
しかし、それは敗北することができます!リモーティングなどで使用されるのと同じ間接参照を使用します。警告-以下は純粋な悪です:
class MyFunnyProxyAttribute : ProxyAttribute {
public override MarshalByRefObject CreateInstance(Type serverType) {
return null;
}
}
[MyFunnyProxy]
class MyFunnyType : ContextBoundObject { }
これを実行するnew()
と、呼び出しはプロキシ(MyFunnyProxyAttribute
)にリダイレクトされ、プロキシが戻りますnull
。さあ、目を洗ってください!