Як перевірити, чи є об'єкт певного типу


102

Я передаю різні об'єкти в підпрограму, щоб запустити один і той же процес, але кожен раз використовуючи інший об'єкт. Наприклад, в одному випадку я використовую ListView, а в іншому випадку я передаю DropDownList.

Я хочу перевірити, чи передається об'єкт є DropDownList, а потім виконати якийсь код, якщо він є. Як це зробити?

Мій код поки що не працює:

Sub FillCategories(ByVal Obj As Object)
    Dim cmd As New SqlCommand("sp_Resources_Categories", Conn)
    cmd.CommandType = CommandType.StoredProcedure
    Obj.DataSource = cmd.ExecuteReader
    If Obj Is System.Web.UI.WebControls.DropDownList Then

    End If
    Obj.DataBind()
End Sub

Відповіді:


159

У VB.NET потрібно використовувати GetTypeметод для отримання типу екземпляра об'єкта, а GetType()оператор - для вибору іншого відомого типу.

Коли у вас є два типи, ви можете просто порівняти їх за допомогою Isоператора.

Отже, ваш код повинен бути насправді записаний так:

Sub FillCategories(ByVal Obj As Object)
    Dim cmd As New SqlCommand("sp_Resources_Categories", Conn)
    cmd.CommandType = CommandType.StoredProcedure
    Obj.DataSource = cmd.ExecuteReader
    If Obj.GetType() Is GetType(System.Web.UI.WebControls.DropDownList) Then

    End If
    Obj.DataBind()
End Sub

Ви також можете використовувати TypeOfоператор замість GetTypeметоду. Зауважте, що це тестує, якщо ваш об'єкт сумісний із заданим типом, а не той самий тип. Це виглядатиме так:

If TypeOf Obj Is System.Web.UI.WebControls.DropDownList Then

End If

Цілком тривіальна, нерелевантна нитка: традиційно імена параметрів є camelCrozen (це означає, що вони завжди починаються з малої літери) при написанні коду .NET (або VB.NET або C #). Це дозволяє їх легко відрізнити з першого погляду від класів, типів, методів тощо.


1
Дякую за вашу відповідь. Я спробував цей код, але насправді єдине, що він не працює з оператором '='. Мені довелося змінити це на "Є". Помилка, що була у мене, коли було "=", була "Оператор" = ", не визначена для типів" System.Type "і" System.Type "."
Лія

1
@ Так: Так, вибач за це. Схоже, мені слід почати приділяти більше уваги, коли пишуть відповіді. TypeOfце, мабуть, ще простіший варіант, принаймні з точки зору читабельності коду; Я також оновив відповідь на прикладі цього.
Коді Грей

35
Існує важлива відмінність між цими двома, саме це і призвело мене до цієї посади. Перевірка TypeOf поверне значення True, якщо об'єкт класу, який успадковується від типу, на який ви перевіряєте, тоді як GetType поверне True лише у тому випадку, коли це точно той самий клас.
Абак

Цілком тривіальний, невідповідний контрапункт: Хоча VS CodeAnalysis скаржиться, я все ще вважаю, що назви аргументів є частиною загальнодоступного інтерфейсу, і тому PascalCase в моєму коді.
Марк Херд

Чи є різниця в продуктивності між ними? - А як Select Case (Obj.GetType())із кількома тестовими випадками Vs кратними IF TypeOf Obj is ...?
Люк Т О'Брайен

3

Ще кілька деталей стосовно відповіді Коді Грей. Оскільки мені знадобилося певний час, щоб переварити його, хоча це може бути корисним для інших.

По-перше, деякі визначення:

  1. Є TypeNames, які представляють собою рядкові представлення типу об'єкта, інтерфейсу тощо. Наприклад, Barце TypeName в Public Class Bar, або в Dim Foo as Bar. TypeNames можна розглядати як "мітки", що використовуються в коді, щоб повідомити компілятору, яке визначення типу шукати в словнику, де будуть описані всі доступні типи.
  2. Є System.Typeоб'єкти, які містять значення. Це значення вказує на тип; так само, як a Stringвзяв би текст або an Intвзяв би число, за винятком того, що ми зберігаємо типи замість тексту чи цифр. Typeоб'єкти містять визначення типів, а також відповідне ім’я TypeName.

По-друге, теорія:

  1. Foo.GetType()повертає Typeоб'єкт, який містить тип змінної Foo. Іншими словами, це говорить вам, що Fooтаке екземпляр.
  2. GetType(Bar)повертає Typeоб'єкт, який містить тип для TypeName Bar.
  3. У деяких випадках тип об'єкта, який має бути Cast, відрізняється від типу, з якого вперше створено інстанціювання. У наступному прикладі MyObj - це передача Integerу Object:

    Dim MyVal As Integer = 42 Dim MyObj As Object = CType(MyVal, Object)

Отже, буває MyObjтипу Objectчи типу Integer?MyObj.GetType()скаже вам, що це Integer.

  1. Але тут з'являється Type Of Foo Is Barфункція, яка дозволяє встановити, чи змінна Fooсумісна з TypeName Bar. Type Of MyObj Is Integerі Type Of MyObj Is Objectобидва повернуть True. У більшості випадків TypeOf вказує, що змінна сумісна з TypeName, якщо змінна такого типу або Type, що походить від неї. Більше інформації тут: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks

Тест, наведений нижче, досить добре ілюструє поведінку та використання кожного із згаданих ключових слів та властивостей.

Public Sub TestMethod1()

    Dim MyValInt As Integer = 42
    Dim MyValDble As Double = CType(MyValInt, Double)
    Dim MyObj As Object = CType(MyValDble, Object)

    Debug.Print(MyValInt.GetType.ToString) 'Returns System.Int32
    Debug.Print(MyValDble.GetType.ToString) 'Returns System.Double
    Debug.Print(MyObj.GetType.ToString) 'Returns System.Double

    Debug.Print(MyValInt.GetType.GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(MyValDble.GetType.GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(MyObj.GetType.GetType.ToString) 'Returns System.RuntimeType

    Debug.Print(GetType(Integer).GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(GetType(Double).GetType.ToString) 'Returns System.RuntimeType
    Debug.Print(GetType(Object).GetType.ToString) 'Returns System.RuntimeType

    Debug.Print(MyValInt.GetType = GetType(Integer)) '# Returns True
    Debug.Print(MyValInt.GetType = GetType(Double)) 'Returns False
    Debug.Print(MyValInt.GetType = GetType(Object)) 'Returns False

    Debug.Print(MyValDble.GetType = GetType(Integer)) 'Returns False
    Debug.Print(MyValDble.GetType = GetType(Double)) '# Returns True
    Debug.Print(MyValDble.GetType = GetType(Object)) 'Returns False

    Debug.Print(MyObj.GetType = GetType(Integer)) 'Returns False
    Debug.Print(MyObj.GetType = GetType(Double)) '# Returns True
    Debug.Print(MyObj.GetType = GetType(Object)) 'Returns False

    Debug.Print(TypeOf MyObj Is Integer) 'Returns False
    Debug.Print(TypeOf MyObj Is Double) '# Returns True
    Debug.Print(TypeOf MyObj Is Object) '# Returns True


End Sub

EDIT

Ви також можете використати Information.TypeName(Object)для отримання TypeName даного об'єкта. Наприклад,

Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.