Является ли объект словарем любого TKey и TValue (не получить TKey и TValue) - PullRequest
0 голосов
/ 01 сентября 2018

Надеюсь, на этот вопрос где-то не было ответа, но я действительно понятия не имею, что искать.

У меня есть переменная, которая определяется только как объект (я знаю, я знаю, избегайте этого)

Я пытаюсь определить, что это во время выполнения, чтобы я мог перейти к правильному обработчику. Для этого я использую 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 голосов
/ 01 сентября 2018

Возможно, есть лучший способ, но вот что будет работать:

Dim t = obj.GetType()

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

EDIT:

На самом деле, есть лучший способ:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...