具有泛型的VB类型运算符 [英] VB typeof operator with generics

查看:162
本文介绍了具有泛型的VB类型运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在VB中比较类型时,以下方式可以正常工作,并且可以将当前实例与特定的继承类进行比较,在这种情况下返回 False (从 LINQPad

  Sub Main 
Dim a As New MyOtherChildClass

a.IsType()。Dump()
End Sub

'在这里定义其他方法和类
MustInherit类MyBaseClass
Public Function IsType()As Boolean
返回TypeOf Me MyChildClass
End Function
End Class

类MyChildClass
继承MyBaseClass
结束类

类MyOtherChildClass
继承MyBaseClass
结束类

但是,当引入泛型时,VB编译器会失败并返回错误类型为'UserQuery.MyBaseClass(Of T)'的表达式永远不能是'UserQuery.MyChildClass '。



<$
MustInherit类MyBaseClass(Of T)
公共函数IsType()作为布尔
返回TypeOf Me MyChildClass
结束函数
结束类

类MyChildClass
继承MyBaseClass(Of String)
结束类

类MyOtherChildClass
继承MyBaseClass(Of String)
End Class

C# / strong>编译并允许比较,返回正确的结果


$ b

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

a.IsType()。Dump();
}

//在这里定义其他方法和类

抽象类MyBaseClass< T>
{
public bool IsType()
{
return this MyChildClass;
}
}

class MyChildClass:MyBaseClass< string>
{
}

class MyOtherChildClass:MyBaseClass< string>
{
}

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

解决方案

您提出了一个有关VB / C#编译的有趣观点,我无法真正了解。如果您正在寻找解决方案,可以通过如何识别泛型类?这个问题来实现。



定义这些函数:


$ b

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

返回IsSubclassOf(childType,parentType ,isParentGeneric)
End Function

Private Function IsSubclassOf(ByVal childType As Type,ByVal parentType As Type,ByVal isParentGeneric As Boolean)As Boolean
如果childType是Nothing那么
返回False
End If

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

If childType是parentType Then
返回True
End If

返回IsSubclassOf(childType.BaseType,parentType,isParentGeneric)
End Function

像这样调用:
$ b

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

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

以下是 Microsoft Connect Ticket 可能会解决这个问题并给出一些解释,一个功能或一般的键入错误。



尽管这种情况似乎并不支持 类型 文档说明对于类,typeof将在以下情况下返回true:


$ b


objectexpression 类型 typename typename继承


When comparing types in VB the following works as expected and enables the current instance to be compared against a specific inherited class, in this case returning False (snippet from 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

However when generics are introduced the VB compiler fails with the error 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

The equivalent code in C# compiles and allows the comparison, returning the correct result

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>
{
}

Why does the VB compiler not allow this comparison?

解决方案

You raise an interesting point about VB/C# compilation that I can't really speak to. If you're looking for a solution, here's a way to do it from the question How can I recognize a generic class?

Define these functions:

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

Call like this:

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

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

Here's a Microsoft Connect Ticket that might deal with this issue and give some explanation as to whether this was a feature or a bug of generic typing.

Although this case doesn't seem supported by the Type Of documentation which states that for classes, typeof will return true if:

objectexpression is of type typename or inherits from typename

这篇关于具有泛型的VB类型运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆