我收集了一些极端情况和脑筋急转弯,并且总是希望听到更多。该页面仅真正涵盖了C#语言的某些方面,但我也发现.NET的核心内容也很有趣。例如,这不是页面上的,但是我发现它令人难以置信:
string x = new string(new char[0]); string y = new string(new char[0]); Console.WriteLine(object.ReferenceEquals(x, y));
我希望打印出False-毕竟,“ new”(具有引用类型) 总是 创建一个新对象,不是吗?C#和CLI的规范都表明应该这样做。好吧,不是在这种情况下。它显示True,并且已经在我测试过的框架的每个版本上完成。(坦率地说,我还没有在Mono上尝试过…)
需要明确的是,这仅是我正在寻找的一种示例- 我并不是特别希望对此奇怪现象进行讨论/解释。(这与普通的字符串实习不同;特别是,在调用构造函数时,通常不会发生字符串实习。)我真的在要求类似的奇怪行为。
还有其他宝石潜伏在那里吗?
我想我曾经给你看过这个,但是我喜欢这里的乐趣-这需要一些调试才能找到答案!(原始代码显然更加复杂和微妙…)
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
Nullable<T>
int?
更新:剧情变厚了……Ayende Rahien 在他的博客上提出了类似的挑战,但带有where T : class, new():
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。现在去洗眼睛!
new()
MyFunnyProxyAttribute
null