Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# 7.2 default expression and Equals (bug?)

I'm using Visual Studion 2017 version 15.5.2, and C# version 7.2. To the point:

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

But if I use ValueTuple:

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

Is it supposed to be like this?

like image 274
lisz Avatar asked Nov 28 '22 13:11

lisz


2 Answers

Is this Windows Forms?

Because in WinForms, System.Drawing.Color.Equals() doesn't have an overload that takes a Color. Instead, it only has the one from Object. In WPF, System.Windows.Media.Color.Equals() contains an overload that takes a Color.

When default is passed as an argument to Color.Equals(Object), what gets passed is default(Object) since the compiler infers Object to be the type based on its signature. From the docs:

The default literal produces the same value as the equivalent default(T) where T is the inferred type.

Clearly, default(Color) isn't equivalent to default(Object), since Color is a value type and Object is a reference type (which defaults to null).

ValueTuple.Equals(), on the other hand, takes another ValueTuple, so the compiler has no trouble inferring the type of default as default(ValueTuple).

Edit:

As of .NET Core 2.0, System.Drawing.Color.Equals() does have an overload that takes a Color. The compiler would have no trouble inferring the type of default as default(Color); therefore, it would now return true.

like image 103
BoltClock Avatar answered Dec 15 '22 23:12

BoltClock


@fharreau is correct: System.Drawing.Color does not implement an Equals(Color) method, so $"{t.Equals(default)}" binds to the only method available: Equals(Object). Thus, default resolves to default(Object) or null.

If you use System.Windows.Media.Color from WPF, which does implement Equals(Color), then you'll see the expected results:

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

ValueTuple also provides an Equals to compare against another tuple, which is why you saw the expected result.

like image 35
Mike Strobel Avatar answered Dec 15 '22 22:12

Mike Strobel