您在 C# 或 .NET 中见过的最奇怪的极端情况是什么? [英] What's the strangest corner case you've seen in C# or .NET?

查看:17
本文介绍了您在 C# 或 .NET 中见过的最奇怪的极端情况是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收集了一些边角案例和 脑筋急转弯,并且总是喜欢听到更多.该页面只真正涵盖了 C# 语言的一些细节,但我也发现核心 .NET 的东西也很有趣.例如,这里有一个不在页面上但我觉得不可思议的:

I collect a few corner cases and brain teasers and would always like to hear more. The page only really covers C# language bits and bobs, but I also find core .NET things interesting too. For example, here's one which isn't on the page, but which I find incredible:

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 上尝试过...)

I'd expect that to print False - after all, "new" (with a reference type) always creates a new object, doesn't it? The specs for both C# and the CLI indicate that it should. Well, not in this particular case. It prints True, and has done on every version of the framework I've tested it with. (I haven't tried it on Mono, admittedly...)

要清楚,这只是我正在寻找的那种东西的一个例子 - 我并不是特别想讨论/解释这种奇怪的东西.(这与普通的字符串实习不同;特别是,在调用构造函数时通常不会发生字符串实习.)我真的要求类似的奇怪行为.

Just to be clear, this is only an example of the kind of thing I'm looking for - I wasn't particularly looking for discussion/explanation of this oddity. (It's not the same as normal string interning; in particular, string interning doesn't normally happen when a constructor is called.) I was really asking for similar odd behaviour.

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

Any other gems lurking out there?

推荐答案

我想我之前向您展示过这个,但我喜欢这里的乐趣 - 这需要一些调试才能找到!(原来的代码显然更加复杂微妙……)

I think I showed you this one before, but I like the fun here - this took some debugging to track down! (the original code was obviously more complex and subtle...)

    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 - 例如 int?.所有方法都被覆盖,除了 GetType() 不能被覆盖;所以它被转换(装箱)到对象(并因此为空)来调用 object.GetType()... 调用 null ;-p

Answer: any Nullable<T> - such as int?. All the methods are overridden, except GetType() which can't be; so it is cast (boxed) to object (and hence to null) to call object.GetType()... which calls on null ;-p

更新:情节变浓了... Ayende Rahien 扔了一个 他的博客上有类似的挑战,但有一个 where T : class, new():

Update: the plot thickens... Ayende Rahien threw down a similar challenge on his blog, but with a 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?");
}

但它可以被打败!使用与远程处理相同的间接方式;警告 - 以下是纯粹的邪恶:

But it can be defeated! Using the same indirection used by things like remoting; warning - the following is pure evil:

class MyFunnyProxyAttribute : ProxyAttribute {
    public override MarshalByRefObject CreateInstance(Type serverType) {
        return null;
    }
}
[MyFunnyProxy]
class MyFunnyType : ContextBoundObject { }

有了这个,new() 调用被重定向到代理 (MyFunnyProxyAttribute),它返回 null.现在去洗你的眼睛!

With this in place, the new() call is redirected to the proxy (MyFunnyProxyAttribute), which returns null. Now go and wash your eyes!

这篇关于您在 C# 或 .NET 中见过的最奇怪的极端情况是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆