我收集了一些极端案例和脑筋急转弯,总是想听到更多。这个页面只涵盖了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上尝试过……)

只是为了澄清,这只是我正在寻找的事情的一个例子-我并不是特别寻找对这个奇怪现象的讨论/解释。(这和普通的弦乐实习不一样;特别地,当调用构造函数时,字符串实习通常不会发生。)我真的是在要求类似的奇怪行为。

还有其他的宝藏吗?


当前回答

分配!


这是我在聚会上喜欢问的一个问题(这可能是我不再被邀请的原因):

你能编译下面这段代码吗?

    public void Foo()
    {
        this = new Teaser();
    }

一个简单的欺骗可以是:

string cheat = @"
    public void Foo()
    {
        this = new Teaser();
    }
";

但真正的解决方案是:

public struct Teaser
{
    public void Foo()
    {
        this = new Teaser();
    }
}

值类型(结构体)可以重新赋值它们的this变量,这是一个小常识。

其他回答

下面将打印False而不是抛出溢出异常:

Console.WriteLine("{0}", yep(int.MaxValue ));


private bool yep( int val )
{
    return ( 0 < val * 2);
}

这是我最近才发现的一个……

interface IFoo
{
   string Message {get;}
}
...
IFoo obj = new IFoo("abc");
Console.WriteLine(obj.Message);

乍一看,上述做法很疯狂,但实际上是合法的。不,真的(虽然我错过了一个关键部分,但它不是任何像“添加一个称为IFoo的类”或“添加一个使用别名将IFoo指向一个类”这样的俗套)。

看看你是否能找出原因:谁说你不能实例化一个接口?

我认为这个问题的答案是因为。net使用字符串实习,这可能会导致相同的字符串指向相同的对象(因为字符串是可变的,这不是一个问题)

(我说的不是string类上重写的相等运算符)

我发现了第二个非常奇怪的极端情况,远远超过了我的第一个。

字符串。Equals Method (String, String, StringComparison)实际上并不是没有副作用的。

我当时在写一段代码,在某个函数的顶部有一行这样的代码:

stringvariable1.Equals(stringvariable2, StringComparison.InvariantCultureIgnoreCase);

删除这一行将导致程序中其他地方的堆栈溢出。

这段代码实际上是在为BeforeAssemblyLoad事件安装一个处理程序,并尝试执行该处理程序

if (assemblyfilename.EndsWith("someparticular.dll", StringComparison.InvariantCultureIgnoreCase))
{
    assemblyfilename = "someparticular_modified.dll";
}

到现在我都不用告诉你了。在字符串比较中使用从未使用过的区域性会导致程序集负载。InvariantCulture也不例外。

如果你有扩展方法:

public static bool? ToBoolean(this string s)
{
    bool result;

    if (bool.TryParse(s, out result))
        return result;
    else
        return null;
}

这段代码:

string nullStr = null;
var res = nullStr.ToBoolean();

这不会抛出异常,因为它是一个扩展方法(实际上是HelperClass.ToBoolean(null)),而不是一个实例方法。这可能会令人困惑。