Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload resolution with CType'd Enum

Consider the following minimal example:

Module Module1
    Private Enum MyEnum
        A
    End Enum

    Public Sub Main(args As String())
        AreEqual(CType(0, MyEnum), MyEnum.A)    ' Error here
    End Sub

    Private Function AreEqual(Of T)(item1 As T, item2 As T) As Boolean
        Return False
    End Function

    Private Function AreEqual(item1 As Object, item2 As Object) As Boolean
        Return False
    End Function
End Module

For some strange reason, overload resolution fails in the line marked with "Error here":

Error 6 Overload resolution failed because no accessible 'AreEqual' is most specific for these arguments:

Private Function AreEqual(item1 As Object, item2 As Object) As Boolean: Not most specific.

Private Function AreEqual(Of MyEnum)(item1 As MyEnum, item2 As MyEnum) As Boolean: Not most specific.

Why is the second function not "most specific"? Both CType(0, MyEnum) and MyEnum.A should be expressions that are statically typed as MyEnum.

Interestingly, I can only reproduce this problem with casting an Enum. AreEqual(CType(0, Int32), 0) and AreEqual(MyEnum.A, MyEnum.A) both compile without problems.

I know how to fix this. I know that I can just use AreEqual(Of MyEnum)(...). That is not the question. I'm curious why this happens. Some compiler bug? Interestingly, the corresponding C# code does work:

enum MyEnum { A, B }
static void Main(string[] args)
{
    AreEqual((MyEnum)0, MyEnum.A);
}

static bool AreEqual<T>(T item1, T item2) { return false; }
static bool AreEqual(object item1, object item2) { return false; }
like image 423
Heinzi Avatar asked Mar 05 '15 15:03

Heinzi


1 Answers

It's related to integers, specifically zero. I think it's some not-quite-defined Option Strict artefact. I note default return type (in Intellisense) for CType() is object. Interestingly, doing any of these things removes the error:

  • Giving MyEnum any type, other than integer
  • AreEqual(0, MyEnum.A)
  • AreEqual(CType(1, MyEnum), MyEnum.A)

Yep. Crazy stuff, good find Heinzi!

like image 122
Chalky Avatar answered Oct 23 '22 21:10

Chalky