具有泛型的VB类型运算符 [英] VB typeof operator with generics
问题描述
在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屋!