c#7.2默认表达式和Equals(bug?)

lis*_*isz 4 c# default valuetuple c#-7.2

我正在使用Visual Studion 2017版本15.5.2和C#版本7.2.要点:

Color c = default;                              // or: c = default(Color); no difference
Debug.Print($"{c.Equals(default(Color))}");     // true
Debug.Print($"{c.Equals(default)}");            // false WHY?!
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用ValueTuple:

(string s, int i) t = default;                  
Debug.Print($"{t.Equals(default((string, int)))}"); // true
Debug.Print($"{t.Equals(default)}");                // true
Run Code Online (Sandbox Code Playgroud)

它应该是这样的吗?

Bol*_*ock 6

这是Windows窗体吗?

因为在WinForms中,System.Drawing.Color.Equals()没有需要的重载Color.相反,它只有一个来自Object.在WPF中,System.Windows.Media.Color.Equals()包含一个需要Color的重载.

default作为参数传递时Color.Equals(Object),传递的内容是default(Object)因为编译器Object根据其签名推断出类型.来自文档:

default文字产生相同的值作为等效default(T)其中T是推断出的类型.

显然,default(Color)不等价default(Object),因为它Color是一个值类型,并且Object是一个引用类型(默认为null).

ValueTuple.Equals(),另一方面,另需ValueTuple,所以编译器没有麻烦推断的类型defaultdefault(ValueTuple).


Mik*_*bel 5

@fharreau是正确的:System.Drawing.Color没有实现Equals(Color)方法,因此$"{t.Equals(default)}"绑定到唯一可用的方法:Equals(Object).因此,default解决default(Object)null.

如果您使用System.Windows.Media.ColorWPF,它确实实现了Equals(Color),那么您将看到预期的结果:

System.Windows.Media.Color c = default;
Console.WriteLine($"{c.Equals(default(System.Windows.Media.Color))}");  // true
Console.WriteLine($"{c.Equals(default)}");                              // true
Run Code Online (Sandbox Code Playgroud)

ValueTuple还提供了Equals与另一个元组进行比较的原因,这就是为什么你看到了预期的结果.


Dav*_*idG 5

在第一个代码块中,该.Equals()方法来自基object类,这意味着default它将是默认值object而不是Color.这就是它返回false的原因.

.Equals()然而,元组方法已被覆盖以采用相关类型,该函数的内部比较各个组件.从文档中,如果符合以下条件,则ValueTuple被视为相等:

  • 其组件与当前实例的组件类型相同.
  • 其组件与当前实例的组件相同.平等由每个组件的默认相等比较器确定.