带有泛型的VB typeof运算符

时间:2013-08-15 03:05:35

标签: vb.net generics typeof

在比较VB中的类型时,以下按预期工作,并将当前实例与特定的继承类进行比较,在这种情况下返回False(来自LINQPad的片段)

Sub Main
    Dim a As New MyOtherChildClass

    a.IsType().Dump()
End Sub

' Define other methods and classes here
MustInherit class MyBaseClass
    Public Function IsType() As Boolean
        Return TypeOf Me Is MyChildClass
    End Function
End Class

Class MyChildClass 
    Inherits MyBaseClass
End Class

Class MyOtherChildClass
    Inherits MyBaseClass
End Class

但是,当引入泛型时,VB编译器会因错误Expression of type 'UserQuery.MyBaseClass(Of T)' can never be of type 'UserQuery.MyChildClass'.

而失败
' Define other methods and classes here
MustInherit class MyBaseClass(Of T)
    Public Function IsType() As Boolean
        Return TypeOf Me Is MyChildClass
    End Function
End Class

Class MyChildClass 
    Inherits MyBaseClass(Of String)
End Class

Class MyOtherChildClass
    Inherits MyBaseClass(Of String)
End Class

C#中的等效代码编译并允许比较,返回正确的结果

void Main()
{
    var a = new MyOtherChildClass();

    a.IsType().Dump();
}

// Define other methods and classes here

abstract class MyBaseClass<T>
{
    public bool IsType()
    {
        return this is MyChildClass;
    }
}

class MyChildClass : MyBaseClass<string>
{
}

class MyOtherChildClass : MyBaseClass<string>
{
}

为什么VB编译器不允许这种比较?

2 个答案:

答案 0 :(得分:2)

你提出了一个关于VB / C#编译的一个有趣的观点,我真的不能说。如果您正在寻找解决方案,可以通过问题How can I recognize a generic class?

来实现

定义这些功能:

Public Function IsSubclassOf(ByVal childType As Type, ByVal parentType As Type) As Boolean
    Dim isParentGeneric As Boolean = parentType.IsGenericType

    Return IsSubclassOf(childType, parentType, isParentGeneric)
End Function

Private Function IsSubclassOf(ByVal childType As Type, ByVal parentType As Type, ByVal isParentGeneric As Boolean) As Boolean
    If childType Is Nothing Then
        Return False
    End If

    If isParentGeneric AndAlso childType.IsGenericType Then
        childType = childType.GetGenericTypeDefinition()
    End If

    If childType Is parentType Then
        Return True
    End If

    Return IsSubclassOf(childType.BaseType, parentType, isParentGeneric)
End Function

这样打电话:

Dim baseType As Type = GetType(MyBaseClass(Of ))
Dim childType As Type = GetType(MyOtherChildClass)

Console.WriteLine(IsSubclassOf(childType, baseType))
'Writes: True

这是一个Microsoft Connect Ticket可能会解决这个问题,并对这是一个功能还是泛型类型的错误提供一些解释。

虽然Type Of文档似乎不支持这种情况,但是对于类,如果出现以下情况,typeof将返回true:

  

objectexpression 属于 typename typename继承

答案 1 :(得分:0)

我熟悉C#,但对VB不太熟悉。但是,示例VB代码和示例C#代码似乎不同。在VB示例中,您使用Return TypeOf Me Is MyChildClass,它在C#中将是return typeof(this) is MyChildClass;。但是(据说可行的)C#示例只有return this is MyChildClass;

我希望TypeOf Me Is MyChildClass询问是否可以将左侧的实例表达式(Type)分配给声明为右侧类型的变量(MyChildClass )。由于框架类Type与您的MyChildClass没有任何关联,因此这是不可能的,因此编译器可能会收到警告或错误的错误 - 可能是您正在获取的错误。 / p>

相反,我认为VB代码应该是Return Me Is MyChildClass以匹配C#示例,它应该正确地询问是否可以将实例Me分配给声明为MyChildClass的变量。如果使用这种语法,VB仍然会反对,还是修复了错误并获得了正确的行为?