使用CType'd Enum重载分辨率

时间:2015-03-05 15:41:05

标签: c# vb.net casting enums overload-resolution

考虑以下最小例子:

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

由于某些奇怪的原因,标记为&#34的行中的重载解析失败;此处出现错误":

  

错误6重载解析失败,因为无法访问' AreEqual'这些论点最具体:

     

Private Function AreEqual(item1 As Object, item2 As Object) As Boolean:不是最具体的。

     

Private Function AreEqual(Of MyEnum)(item1 As MyEnum, item2 As MyEnum) As Boolean:不是最具体的。

为什么第二个功能不是"最具体的"? CType(0, MyEnum)MyEnum.A都应该是静态类型为{{1}的表达式}。

有趣的是,我只能通过投射枚举来重现这个问题。 MyEnumAreEqual(CType(0, Int32), 0)都可以毫无问题地编译。

我知道如何解决这个问题。我知道我可以使用AreEqual(MyEnum.A, MyEnum.A)。这不是问题。我好奇为什么会发生这种情况。一些编译器bug?有趣的是,相应的C#代码确实工作:

AreEqual(Of MyEnum)(...)

3 个答案:

答案 0 :(得分:1)

它与整数有关,特别是零。我认为它是一些不太明确的Option Strict artefact。我注意到CType()的默认返回类型(在Intellisense中)是对象。有趣的是,执行上述任何操作都会消除错误:

  • 为MyEnum提供除整数
  • 以外的任何类型
  • AreEqual(0,MyEnum.A)
  • AreEqual(CType(1,MyEnum),MyEnum.A)

是的。疯狂的东西,很好找到Heinzi!

答案 1 :(得分:0)

我无可否认地在这里,但以下不会产生任何错误。

AreEqual(CType(CType(0, Int16), MyEnum), MyEnum.A) 

在哪里

AreEqual(CType(CType(0, Integer), MyEnum), MyEnum.A) 

一样。

AreEqual(CType(1, MyEnum), MyEnum.A)

也编译好。

道歉,如果这是无稽之谈或没用。

答案 2 :(得分:0)

我认为你的问题是你没有限制你的泛型类型T.所以它也可以是一个对象。

即。如果T是object类型,那么当编译器翻译成公共中间语言时,它们是相同的:

 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

我不明白为什么你们两个都需要。 T将迎合对象。那么只需删除第二个,一切都应该有用吗?