我想我之前向你展示过这个,但我喜欢这里的趣味 - 这需要一些调试才能追踪到!(原始代码显然更复杂和微妙...)
static void Foo<T>() where T : new()
{
T t = new T();
Console.WriteLine(t.ToString());
Console.WriteLine(t.GetHashCode());
Console.WriteLine(t.Equals(t));
Console.WriteLine(t.GetType());
}
所以,什么是Nullable<T>
- 比如int?
。除了GetType()方法不能被覆盖,其余所有方法都被覆盖;因此它被强制转换(装箱)为对象(因此为null),以调用object.GetType()...这将在空值上调用;-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();
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
。现在去洗洗眼睛吧!