How to check if an object is a certain type

前端 未结 2 2118
予麋鹿
予麋鹿 2020-12-13 16:37

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 ca

相关标签:
2条回答
  • 2020-12-13 17:31

    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:

    1. There are TypeNames, which are string representations of the type of an object, interface, etc. For example, Bar is a TypeName in Public Class Bar, or in Dim 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.
    2. There are System.Type objects which contain a value. This value indicates a type; just like a String would take some text or an Int 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:

    1. Foo.GetType() returns a Type object which contains the type for the variable Foo. In other words, it tells you what Foo is an instance of.
    2. GetType(Bar) returns a Type object which contains the type for the TypeName Bar.
    3. 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 an Integer cast into an Object:

      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.

    1. But here comes the Type Of Foo Is Bar feature, which allows you to ascertain a variable Foo is compatible with a TypeName Bar. Type Of MyObj Is Integer and Type 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"
    
    0 讨论(0)
  • 2020-12-13 17:34

    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.

    0 讨论(0)
提交回复
热议问题