Roslyn: Overload resolution for float prefers enum over object

Created on 19 Feb 2019  路  7Comments  路  Source: dotnet/roslyn

Version Used:
Microsoft (R) Visual C# Compiler version 2.8.2.62916 (2ad4aabc)

Steps to Reproduce:

  1. Compile and run the following test case

```using System;
class Program
{
enum MyEnum { Zero }
static void Main(string[] args) {
Print(0.0f);
Print(0.1f);
}

static void Print(object a) {
    Console.WriteLine(a);
}

static void Print(MyEnum e) {
    Console.WriteLine(e);
}

}
```

Expected Behavior:
0
0.1

Actual Behavior:
Zero
0.1

Corresponds to Unity issue: https://issuetracker.unity3d.com/issues/gameobject-dot-sendmessage-doesnt-accept-value-as-a-function-argument-correctly-in-the-net-4-dot-x-scripting-runtime

Area-Compilers Feature Request New Feature - Warning Waves

Most helpful comment

This is one place where we might be able to add a warning (in a warning wave) when you accidentally tickle this bug.

All 7 comments

@gafter can confirm but I believe this is following specified behavior for the C# language.

There exists an implicit conversion from float to MyEnum and that is more specific than object.

@joncham was this working as you expect in a previous version of the compiler?

That is unexpected. Isn't the default enum int-based? So why is there an implicit conversion from float? We can't do a float-to-int implicitly, so why does the enum get to?

It鈥檚 my understanding that this was added to csc.exe purposefully by Eric Lippert back in 2006.

If there鈥檚 any desire to change it back, I imagine there are monumental back-compat concerns, even if the premature optimization mentioned in the related blog posts has been removed.

@mattleibow There鈥檚 an implicit conversion from a _literal zero_, which the compiler sometimes (has in the past, at least) works quite hard at deducing.

Chrisoverzero's comment above is correct; thanks Chris.

This is probably the most embarrassing of my many compiler bugs, and one of my earlier C# compiler bugs.

You can read the whole story here: see Jon's answer and my answer:

https://stackoverflow.com/questions/23762475/

The history of the bug that motivated me to make the bad change in the first place is here:

https://blogs.msdn.microsoft.com/ericlippert/2006/03/28/the-root-of-all-evil-part-one/

https://blogs.msdn.microsoft.com/ericlippert/2006/03/29/the-root-of-all-evil-part-two/

We decided back in 2006 to stop making unnecessary breaking changes and maintain compatibility with the existing implementation, even though it means that a variable of type enum can be assigned 0.0 without a cast, but one of type int cannot.

This is one place where we might be able to add a warning (in a warning wave) when you accidentally tickle this bug.

Yup, agreed that this issue is by design.

Reopening to track adding a warning for this situation.

Was this page helpful?
0 / 5 - 0 ratings