在比较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编译器不允许这种比较?
答案 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仍然会反对,还是修复了错误并获得了正确的行为?