【问题标题】:Is object a dictionary of any TKey and TValue (not get TKey and TValue)对象是任何 TKey 和 TValue 的字典(不获取 TKey 和 TValue)
【发布时间】:2018-09-01 05:42:40
【问题描述】:

希望这个问题没有在某个地方得到回答,但我真的不知道要搜索什么。

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

我试图在运行时确定它是什么,以便我可以分支到正确的处理程序。为此,我将 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 是什么所以要重述,我想匹配它是任何东西的字典,我会弄清楚“任何东西”是什么,但首先我想知道它是不是一本字典。

提前致谢。

【问题讨论】:

  • 如果是字典,为什么要先知道?这对你有什么帮助?

标签: vb.net dictionary generics


【解决方案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) 类型不匹配的泛型类型定义,因此您不能只将其添加到您的Select Case

Case GetType(Dictionary(Of ,))

编辑 2:

我只是把这个可能有用的扩展方法放在一起:

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

例子:

GetType(Dictionary(Of String, String)).MatchesGenericType(Nothing) 'Throws exception
GetType(Dictionary(Of String, String)).MatchesGenericType(GetType(String)) 'Throws exception
GetType(Dictionary(Of String, String)).MatchesGenericType(GetType(List(Of String))) 'Returns False
GetType(Dictionary(Of String, String)).MatchesGenericType(GetType(Dictionary(Of String, String))) 'Returns True
GetType(Dictionary(Of String, String)).MatchesGenericType(GetType(Dictionary(Of ,))) 'Returns True
GetType(Dictionary(Of ,)).MatchesGenericType(GetType(Dictionary(Of String, String))) 'Returns False
GetType(Dictionary(Of ,)).MatchesGenericType(GetType(Dictionary(Of ,))) 'Returns True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多