나는 당신에게 이것을 이전에 보여줬다 고 생각하지만, 나는 여기서 재미를 좋아합니다-이것은 추적하기 위해 약간의 디버깅이 필요했습니다! (원래 코드는 분명히 더 복잡하고 미묘했습니다 ...)
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로)됩니다.
업데이트 : 줄거리가 두껍게 ... 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. 자 가서 눈을 씻으십시오!