我想我曾经给你看过这个,但是我喜欢这里的乐趣-这需要一些调试才能找到答案!(原始代码显然更加复杂和微妙...)
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());
}
那是什么...
答案:任意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()
调用将重定向到proxy(MyFunnyProxyAttribute
),该代理返回null
。现在去洗眼睛!