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

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

还有其他的宝藏吗?


当前回答

我不久前问了一个问题:

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

考虑到:

Bool aBoolValue;

其中aBoolValue被赋值为True或False;

以下文件将无法编译:

Byte aByteValue = aBoolValue ? 1 : 0;

但这将:

Int anIntValue = aBoolValue ? 1 : 0;

提供的答案也很好。

其他回答

Public Class Item
   Public ID As Guid
   Public Text As String

   Public Sub New(ByVal id As Guid, ByVal name As String)
      Me.ID = id
      Me.Text = name
   End Sub
End Class

Public Sub Load(sender As Object, e As EventArgs) Handles Me.Load
   Dim box As New ComboBox
   Me.Controls.Add(box)          'Sorry I forgot this line the first time.'
   Dim h As IntPtr = box.Handle  'Im not sure you need this but you might.'
   Try
      box.Items.Add(New Item(Guid.Empty, Nothing))
   Catch ex As Exception
      MsgBox(ex.ToString())
   End Try
End Sub

输出为“试图读取受保护的内存。”这表明其他记忆已经被破坏了。”

VB。NET、可空值和三元操作符:

Dim i As Integer? = If(True, Nothing, 5)

这花了我一些时间来调试,因为我希望I包含Nothing。

i到底包含了什么?0.

这是令人惊讶的,但实际上是“正确的”行为:在VB中没有。NET与CLR中的null并不完全相同:对于值类型T,没有值可以表示null或默认值(T),这取决于上下文。在上面的例子中,If将Integer推断为Nothing和5的常见类型,因此,在这种情况下,Nothing意味着0。

几年前,在制定忠诚度计划时,我们遇到了一个关于给予客户积分数量的问题。这个问题与将double类型转换为int类型有关。

代码如下:

double d = 13.6;

int i1 = Convert.ToInt32(d);
int i2 = (int)d;

i1 == i2吗?

结果是i1 != i2。 由于Convert和cast运算符的舍入策略不同,实际值为:

i1 == 14
i2 == 13

调用Math. ceiling()或Math. floor()(或Math. ceiling())总是更好。用符合我们要求的midpointrsurround进行四舍五入)

int i1 = Convert.ToInt32( Math.Ceiling(d) );
int i2 = (int) Math.Ceiling(d);

分配!


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

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

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

一个简单的欺骗可以是:

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

但真正的解决方案是:

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

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

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

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

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

stringvariable1.Equals(stringvariable2, StringComparison.InvariantCultureIgnoreCase);

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

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

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

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