对象是任何TKey和TValue的字典(不是获得TKey和TValue)

时间:2018-09-01 05:42:40

标签: vb.net dictionary generics

希望这还没有得到解答,但是我真的不知道要搜索什么。

我有一个仅定义为对象的变量(我知道我知道避免这种情况)

我正在尝试确定运行时的状态,以便可以跳转到正确的处理程序。为此,我将GetType与Select Case一起使用

Select Case obj.GetType()
    Case GetType(String)
        'do something
    Case GetType(Integer)
        'do something
    Case Else
        'throw an error
End Select

,效果很好。问题是它也可能是字典。我需要知道它是否是字典,而不管使用什么泛型来定义字典。我将弄清楚处理程序中的内容。

Case GetType(Dictionary(of Object, Object))

只有在字面意义上是Dictionary(of Object, Object)的情况下才会命中,我想同时对Dictionary(of String, Object)Dictionary(of String, String)Dictionary(of String, Dictionary(of String, Integer))也命中的情况...等

我担心有人会认为我正在尝试确定TValue或TKey是什么以便重述,我想将其匹配为任何东西的字典,我会弄清楚“任何东西”是什么,但首先我想知道它是否甚至是字典。

谢谢。

1 个答案:

答案 0 :(得分:1)

也许有更好的方法,但这是可行的:

Dim t = obj.GetType()

If t.IsGenericType AndAlso
   t.GetGenericTypeDefinition().FullName = "System.Collections.Generic.Dictionary`2" Then

编辑:

实际上,有更好的方法:

If t.IsGenericType AndAlso
   t.GetGenericTypeDefinition() Is GetType(Dictionary(Of ,)) Then

使用GetType时可以省略通用类型参数,但这会创建一个通用类型定义,该定义与任何特定的Dictionary(Of TKey, TValue)类型都不匹配,因此不能将其添加到{{ 1}}:

Select Case

编辑2:

我只是将这种扩展方法放在一起可能有用:

Case GetType(Dictionary(Of ,))

样品用量:

Imports System.Runtime.CompilerServices

Public Module TypeExtensions

    <Extension>
    Public Function MatchesGenericType(source As Type, genericType As Type) As Boolean
        If genericType Is Nothing Then
            Throw New ArgumentNullException(NameOf(genericType))
        End If

        If Not genericType.IsGenericType Then
            Throw New ArgumentException("Value must be a generic type or generic type definition.", NameOf(genericType))
        End If

        Return source.IsGenericType AndAlso
               (source Is genericType OrElse
                source.GetGenericTypeDefinition() Is genericType)
    End Function

End Module

示例:

Module Module1

    Sub Main()
        Dim testTypes = {GetType(String),
                         GetType(List(Of )),
                         GetType(List(Of String)),
                         GetType(Dictionary(Of ,)),
                         GetType(Dictionary(Of String, String))}
        Dim comparisonTypes = {Nothing,
                               GetType(String),
                               GetType(List(Of )),
                               GetType(List(Of String)),
                               GetType(Dictionary(Of ,)),
                               GetType(Dictionary(Of String, String))}

        For Each testType In testTypes
            For Each comparisonType In comparisonTypes
                Console.Write($"Comparing type '{testType.Name}' to {If(comparisonType?.IsGenericTypeDefinition, "type definition", "type")} '{comparisonType?.Name}': ")

                Try
                    Console.WriteLine(testType.MatchesGenericType(comparisonType))
                Catch ex As Exception
                    Console.WriteLine(ex.Message)
                End Try
            Next
        Next

        Console.ReadLine()
    End Sub

End Module