如何在vb.net中忽略类型参数,确定值是否为泛型类型的实例?

如何在vb.net中忽略类型参数,确定值是否为泛型类型的实例?,vb.net,generics,type-parameter,Vb.net,Generics,Type Parameter,我有一个C类(T类)。我想确定某个给定值是否具有类型C,而不管T是什么。例如,我可能想确定一个值是否是强类型列表,而不管该列表存储什么类型的项 我只需要知道如何在VB.net中实现它。在Java中,语法如下所示: var result = obj instanceof Gen2<?>; var result=Gen2的obj实例; 我认为解决您的问题的紧凑解决方案是: Dim result = (obj.GetType().GetGenericTypeDefinition().Eq

我有一个C类(T类)。我想确定某个给定值是否具有类型C,而不管T是什么。例如,我可能想确定一个值是否是强类型列表,而不管该列表存储什么类型的项

我只需要知道如何在VB.net中实现它。在Java中,语法如下所示:

var result = obj instanceof Gen2<?>;
var result=Gen2的obj实例;

我认为解决您的问题的紧凑解决方案是:

Dim result = (obj.GetType().GetGenericTypeDefinition().Equals(GetType(Gen2(Of ))))
说明:

  • 获取表示实例的基本类型的Type对象
    obj
  • 获取编译器实例类型的基础泛型类型
  • 获取不带限定参数的
    Gen2
    的泛型类型
  • 比较两个泛型以查看它们是否相等并返回结果
  • 它没有您发布的Java解决方案那么紧凑(除非我弄错了,C#既不支持instanceof关键字也不支持Java通用通配符语法),但它可以工作

    编辑:根据Cory Larson下面的评论,我应该补充一点,虽然我发布的方法只适用于直接比较泛型和已知泛型类型,但如果您想知道它是否实现了泛型接口,请使用:

    Dim result = (obj.GetType().GetGenericTypeDefinition().GetInterface(GetType(IMyGeneric(Of )).FullName) IsNot Nothing)
    

    我认为解决您的问题的紧凑解决方案是:

    Dim result = (obj.GetType().GetGenericTypeDefinition().Equals(GetType(Gen2(Of ))))
    
    说明:

  • 获取表示实例的基本类型的Type对象
    obj
  • 获取编译器实例类型的基础泛型类型
  • 获取不带限定参数的
    Gen2
    的泛型类型
  • 比较两个泛型以查看它们是否相等并返回结果
  • 它没有您发布的Java解决方案那么紧凑(除非我弄错了,C#既不支持instanceof关键字也不支持Java通用通配符语法),但它可以工作

    编辑:根据Cory Larson下面的评论,我应该补充一点,虽然我发布的方法只适用于直接比较泛型和已知泛型类型,但如果您想知道它是否实现了泛型接口,请使用:

    Dim result = (obj.GetType().GetGenericTypeDefinition().GetInterface(GetType(IMyGeneric(Of )).FullName) IsNot Nothing)
    

    当然,有点。例如:

        Dim obj As IList(Of Double) = New List(Of Double)
        Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
            obj.GetType().GetGenericTypeDefinition().Equals(GetType(IList(Of )))
    
    因此,结果为假。如果您将比较从
    IList(Of)
    更改为仅
    List(Of)
    ,则它可以工作

        Dim obj As IList(Of Double) = New List(Of Double)
        Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
            obj.GetType().GetGenericTypeDefinition().Equals(GetType(List(Of )))
    
    将返回
    True


    编辑:当,丹·斯托里先拿到了。

    当然,有点。例如:

        Dim obj As IList(Of Double) = New List(Of Double)
        Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
            obj.GetType().GetGenericTypeDefinition().Equals(GetType(IList(Of )))
    
    因此,结果为假。如果您将比较从
    IList(Of)
    更改为仅
    List(Of)
    ,则它可以工作

        Dim obj As IList(Of Double) = New List(Of Double)
        Dim result As Boolean = obj.GetType().IsGenericType AndAlso _
            obj.GetType().GetGenericTypeDefinition().Equals(GetType(List(Of )))
    
    将返回
    True


    编辑:Dang,Dan Story首先得到了它。

    如果您想知道某个类型是否是Foo(Of T),因为您对使用不依赖于T的属性感兴趣,我建议您在非泛型基类或非泛型接口中提供该属性。例如,如果定义一个提供类似数组访问的ISuperCollection(Of T),可以提供一个非泛型ISuperCollection集合,该集合实现方法Count、RemoveAt、CompareAt、SwapAt和RotateAt(调用RotateAt(4,3,1))将从项目4开始旋转三个项目,向上旋转一个位置,从而将项目5替换为4,将项目6替换为5,将项目4替换为旧值6),并使ISuperCollection(T的)继承自该项目


    顺便说一句,如果将读卡器接口与写卡器接口分离,读卡器接口可以是协变的,而写卡器接口可以是逆变的。如果任何属性或索引器同时实现读写功能,则需要定义一个读写接口,其中包括任何此类属性或索引器的读写实现;这有点麻烦,但我认为值得付出额外的努力。

    如果您想知道某个类型是否是Foo(Of T),因为您想使用一些不依赖于T的属性,我建议您在非泛型基类或非泛型接口中提供该属性。例如,如果定义一个提供类似数组访问的ISuperCollection(Of T),可以提供一个非泛型ISuperCollection集合,该集合实现方法Count、RemoveAt、CompareAt、SwapAt和RotateAt(调用RotateAt(4,3,1))将从项目4开始旋转三个项目,向上旋转一个位置,从而将项目5替换为4,将项目6替换为5,将项目4替换为旧值6),并使ISuperCollection(T的)继承自该项目


    顺便说一句,如果将读卡器接口与写卡器接口分离,读卡器接口可以是协变的,而写卡器接口可以是逆变的。如果任何属性或索引器同时实现读写功能,则需要定义一个读写接口,其中包括任何此类属性或索引器的读写实现;这有点麻烦,但我认为值得付出额外的努力。

    您显示的语法不是C。C#中没有运算符的
    实例。这是J#语法,它确实支持这个操作符。没错,它是一个Java操作符。我的错误。它仍然不是Java语法。Java没有'var'关键字。您显示的语法不是C#。C#中没有
    运算符的
    实例。这是J#语法,它确实支持这个操作符。没错,它是一个Java操作符。我的错误。它仍然不是Java语法。Java没有“var”关键字。实际情况是我处理的是相关接口和两个级别的泛型嵌套,但您将我设置为可用路径。实际情况是我处理的是相关接口和两个级别的泛型嵌套,但您将我设置为可用路径。