How to check if an object is a certain type
Solution 1
In VB.NET, you need to use the GetType
method to retrieve the type of an instance of an object, and the GetType()
operator to retrieve the type of another known type.
Once you have the two types, you can simply compare them using the Is
operator.
So your code should actually be written like this:
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
You can also use the TypeOf
operator instead of the GetType
method. Note that this tests if your object is compatible with the given type, not that it is the same type. That would look like this:
If TypeOf Obj Is System.Web.UI.WebControls.DropDownList Then
End If
Totally trivial, irrelevant nitpick: Traditionally, the names of parameters are camelCased (which means they always start with a lower-case letter) when writing .NET code (either VB.NET or C#). This makes them easy to distinguish at a glance from classes, types, methods, etc.
Solution 2
Some more details in relation with the response from Cody Gray. As it took me some time to digest it I though it might be usefull to others.
First, some definitions:
- There are TypeNames, which are string representations of the type of an object, interface, etc. For example,
Bar
is a TypeName inPublic Class Bar
, or inDim Foo as Bar
. TypeNames could be seen as "labels" used in the code to tell the compiler which type definition to look for in a dictionary where all available types would be described. - There are
System.Type
objects which contain a value. This value indicates a type; just like aString
would take some text or anInt
would take a number, except we are storing types instead of text or numbers.Type
objects contain the type definitions, as well as its corresponding TypeName.
Second, the theory:
-
Foo.GetType()
returns aType
object which contains the type for the variableFoo
. In other words, it tells you whatFoo
is an instance of. -
GetType(Bar)
returns aType
object which contains the type for the TypeNameBar
. -
In some instances, the type an object has been
Cast
to is different from the type an object was first instantiated from. In the following example, MyObj is anInteger
cast into anObject
:Dim MyVal As Integer = 42 Dim MyObj As Object = CType(MyVal, Object)
So, is MyObj
of type Object
or of type Integer
? MyObj.GetType()
will tell you it is an Integer
.
- But here comes the
Type Of Foo Is Bar
feature, which allows you to ascertain a variableFoo
is compatible with a TypeNameBar
.Type Of MyObj Is Integer
andType Of MyObj Is Object
will both return True. For most cases, TypeOf will indicate a variable is compatible with a TypeName if the variable is of that Type or a Type that derives from it. More info here: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks
The test below illustrate quite well the behaviour and usage of each of the mentionned keywords and properties.
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
You can also use Information.TypeName(Object)
to get the TypeName of a given object. For example,
Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
Related videos on Youtube
Leah
Updated on July 08, 2022Comments
-
Leah almost 2 years
I am passing various objects to a subroutine to run the same process but using a different object each time. For example, in one case I am using a ListView and in another case I am passing a DropDownList.
I want to check if the object being passed is a DropDownList then execute some code if it is. How do I do this?
My code so far which doesn't work:
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
-
Leah almost 13 yearsThanks for your answer. I tried that code but actually the only thing is that it doesn't work with the '=' operator. I had to change it to 'Is'. The error I had when it was '=' was "Operator '=' is not defined for types 'System.Type' and 'System.Type'."
-
Cody Gray almost 13 years@Leah: Yeah, sorry about that. Looks like I should start paying more attention when writing answers.
TypeOf
is probably an even simpler option, at least in terms of code readability; I've updated the answer with an example of that, too. -
Abacus almost 11 yearsThere is an important difference between the two, which is what led me to this post. The TypeOf check will return True if the object is of a class that inherits from the type you are checking against, whereas GetType will only return True if it is exactly the same class.
-
Mark Hurd almost 9 yearsTotally trivial, irrelevant counterpoint: Even though the VS CodeAnalysis complains, I still feel the argument names are part of the public interface and so are PascalCase in my code.
-
Luke T O'Brien about 7 yearsIs there a performance difference between the two? - What about
Select Case (Obj.GetType())
with multiple test cases Vs multipleIF TypeOf Obj is ...
? -
Cristian Rusanu about 4 yearsAnother point worth mentioning: when we need to verify, for example, the exact type of a MemberInfo object that we have through reflection with the type of an actual object, we can use something like:
myMemberInfo.DeclaringType.FullName = myObj.GetType().FullName
. That's because, like Leah mentioned above, we cannot use '=' to compare the actual types.