我收集了一些极端案例和脑筋急转弯,总是想听到更多。这个页面只涵盖了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变量,这是一个小常识。

其他回答

我不久前问了一个问题:

条件运算符不能隐式强制转换?

考虑到:

Bool aBoolValue;

其中aBoolValue被赋值为True或False;

以下文件将无法编译:

Byte aByteValue = aBoolValue ? 1 : 0;

但这将:

Int anIntValue = aBoolValue ? 1 : 0;

提供的答案也很好。

什么时候布尔值既不为真也不为假?

比尔发现你可以破解一个布尔值,如果a为真,B为真,(a和B)为假。

砍布尔值

如果你有扩展方法:

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)),而不是一个实例方法。这可能会令人困惑。

即使枚举函数重载,它们也应该使0为整数。

我知道c#核心团队将0映射到enum的基本原理,但是,它仍然没有像它应该的那样正交。来自Npgsql的例子。

测试的例子:

namespace Craft
{
    enum Symbol { Alpha = 1, Beta = 2, Gamma = 3, Delta = 4 };


   class Mate
    {
        static void Main(string[] args)
        {

            JustTest(Symbol.Alpha); // enum
            JustTest(0); // why enum
            JustTest((int)0); // why still enum

            int i = 0;

            JustTest(Convert.ToInt32(0)); // have to use Convert.ToInt32 to convince the compiler to make the call site use the object version

            JustTest(i); // it's ok from down here and below
            JustTest(1);
            JustTest("string");
            JustTest(Guid.NewGuid());
            JustTest(new DataTable());

            Console.ReadLine();
        }

        static void JustTest(Symbol a)
        {
            Console.WriteLine("Enum");
        }

        static void JustTest(object o)
        {
            Console.WriteLine("Object");
        }
    }
}

下面是一个示例,说明如何创建导致错误消息“试图读写受保护内存”的结构。这通常表明其他记忆被破坏了。” 成功与失败的差别非常细微。

下面的单元测试演示了这个问题。

看看你能不能找出问题出在哪里。

    [Test]
    public void Test()
    {
        var bar = new MyClass
        {
            Foo = 500
        };
        bar.Foo += 500;

        Assert.That(bar.Foo.Value.Amount, Is.EqualTo(1000));
    }

    private class MyClass
    {
        public MyStruct? Foo { get; set; }
    }

    private struct MyStruct
    {
        public decimal Amount { get; private set; }

        public MyStruct(decimal amount) : this()
        {
            Amount = amount;
        }

        public static MyStruct operator +(MyStruct x, MyStruct y)
        {
            return new MyStruct(x.Amount + y.Amount);
        }

        public static MyStruct operator +(MyStruct x, decimal y)
        {
            return new MyStruct(x.Amount + y);
        }

        public static implicit operator MyStruct(int value)
        {
            return new MyStruct(value);
        }

        public static implicit operator MyStruct(decimal value)
        {
            return new MyStruct(value);
        }
    }