一尘不染

您在C#或.NET中看到的最奇怪的极端情况是什么?[关闭]

c#

我收集了一些极端情况和脑筋急转弯,并且总是希望听到更多。该页面仅真正涵盖了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上尝试过…)

需要明确的是,这仅是我正在寻找的一种示例-
我并不是特别希望对此奇怪现象进行讨论/解释。(这与普通的字符串实习不同;特别是,在调用构造函数时,通常不会发生字符串实习。)我真的在要求类似的奇怪行为。

还有其他宝石潜伏在那里吗?


阅读 218

收藏
2020-05-19

共1个答案

一尘不染

我想我曾经给你看过这个,但是我喜欢这里的乐趣-这需要一些调试才能找到答案!(原始代码显然更加复杂和微妙…)

    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。现在去洗眼睛!

2020-05-19