代码之家  ›  专栏  ›  技术社区  ›  Craig Gidney Mihai

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

  •  0
  • Craig Gidney Mihai  · 技术社区  · 15 年前

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

    我只需要知道如何在vb.net中完成。在Java中,语法是这样的:

    var result = obj instanceof Gen2<?>;
    
    3 回复  |  直到 14 年前
        1
  •  4
  •   Dan Story    15 年前

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

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

    说明:

    1. 获取表示实例基类型的类型对象 obj
    2. 获取编译器实例类型的基础泛型类型。
    3. 获取的泛型类型 Gen2 没有限定参数。
    4. 比较两个泛型以查看它们是否相等并返回结果。

    它不像您发布的Java解决方案那么紧凑(除非我错了,C语言不支持关键字的实例或Java通用通配符语法),但它会起作用。

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

    Dim result = (obj.GetType().GetGenericTypeDefinition().GetInterface(GetType(IMyGeneric(Of )).FullName) IsNot Nothing)
    
        2
  •  0
  •   Cᴏʀʏ bcherry    15 年前

    当然,差不多。例如:

        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 )))
    

    为此,结果是 False . 如果你改变比较 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 .

    编辑 当当,丹的故事最先得到。

        3
  •  0
  •   supercat    14 年前

    如果您想找出一个类型是否是foo(of t),因为您对使用一些不依赖t的属性感兴趣,我建议您在非泛型基类或非泛型接口中使用该属性。例如,如果定义一个提供类似数组访问的ISuperCollection(of T),可以提供一个非通用的ISuperCollection集合,该集合实现方法count、removeat、compareat、swapat和rotate a t(调用rotateat(4,3,1)),将从项目4开始旋转三个项目,向上旋转一个点。从而用4替换第5项,用5替换第6项,用旧值6替换第4项,并使isupCollection(of t)从此继承。

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