Как проверить, относится ли объект к определенному типу

Я передаю различные объекты подпрограмме для запуска одного и того же процесса, но каждый раз используя другой объект. Например, в одном случае я использую 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

person Leah    schedule 05.07.2011    source источник


Ответы (2)


В 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

Совершенно тривиальная, неуместная придирка: Традиционно имена параметров пишутся в верблюжьем регистре (что означает, что они всегда начинаются со строчной буквы) при написании кода .NET (либо VB.NET, либо C#). Это позволяет легко отличить их от классов, типов, методов и т. д.

person Cody Gray    schedule 05.07.2011
comment
Спасибо за Ваш ответ. Я пробовал этот код, но на самом деле единственное, что он не работает с оператором '='. Мне пришлось изменить его на «Есть». Ошибка, которая у меня была, когда это было «=», заключалась в том, что оператор «=» не определен для типов «System.Type» и «System.Type». - person Leah; 05.07.2011
comment
@Leah: Да, извини за это. Похоже, мне следует начать уделять больше внимания написанию ответов. TypeOf, вероятно, еще более простой вариант, по крайней мере, с точки зрения читабельности кода; Я также обновил ответ примером этого. - person Cody Gray; 05.07.2011
comment
Между ними есть важное различие, которое и привело меня к этому посту. Проверка TypeOf вернет True, если объект относится к классу, который наследуется от типа, который вы проверяете, тогда как GetType вернет True, только если это точно такой же класс. - person Abacus; 13.08.2013
comment
Совершенно тривиальный, неуместный контраргумент: Несмотря на то, что VS CodeAnalysis жалуется, я по-прежнему считаю, что имена аргументов являются частью общедоступного интерфейса, как и PascalCase в моем коде. - person Mark Hurd; 07.08.2015
comment
Есть ли разница в производительности между ними? - А как насчет Select Case (Obj.GetType()) с несколькими тестовыми примерами по сравнению с несколькими IF TypeOf Obj is ...? - person Luke T O'Brien; 22.05.2017
comment
Еще один момент, о котором стоит упомянуть: когда нам нужно проверить, например, точный тип объекта MemberInfo, который у нас есть через отражение, с типом фактического объекта, мы можем использовать что-то вроде: myMemberInfo.DeclaringType.FullName = myObj.GetType().FullName. Это потому, что, как упоминала Лия выше, мы не можем использовать '=' для сравнения фактических типов. - person Cristian; 06.05.2020

Еще немного подробностей в связи с ответом Коди Грея. Поскольку мне потребовалось некоторое время, чтобы переварить это, я подумал, что это может быть полезно другим.

Сначала несколько определений:

  1. Существуют имена типов, которые являются строковыми представлениями типа объекта, интерфейса и т. д. Например, Bar — это имя типа в Public Class Bar или в Dim Foo as Bar. Имена типов можно рассматривать как «метки», используемые в коде, чтобы сообщить компилятору, какое определение типа искать в словаре, где будут описаны все доступные типы.
  2. Существуют объекты System.Type, содержащие ценность. Это значение указывает тип; точно так же, как String принимает некоторый текст или 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, если переменная имеет этот тип или тип, производный от него. Подробнее здесь: 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

РЕДАКТИРОВАТЬ

Вы также можете использовать Information.TypeName(Object)< /a> для получения TypeName данного объекта. Например,

Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
person Ama    schedule 17.04.2019