【问题标题】:How to check if an object is a certain type如何检查对象是否为某种类型
【发布时间】:2011-09-28 15:10:32
【问题描述】:

我将各种对象传递给子例程以运行相同的进程,但每次都使用不同的对象。例如,在一种情况下,我使用 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

【问题讨论】:

    标签: .net vb.net object drop-down-menu object-type


    【解决方案1】:

    在 VB.NET 中,您需要使用GetType method 来检索对象实例的类型,并使用GetType() operator 来检索另一个已知类型的类型。

    一旦有了这两种类型,您就可以使用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 operator 代替GetType 方法。请注意,这会测试您的对象是否与给定类型兼容,而不是测试它是否是同一类型。看起来像这样:

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

    完全无关紧要的吹毛求疵: 在编写 .NET 代码(VB.NET 或 C#)时,参数名称传统上是驼峰式(这意味着它们总是以小写字母开头) .这使得它们一目了然地与类、类型、方法等区分开来。

    【讨论】:

    • 感谢您的回答。我尝试了该代码,但实际上唯一的问题是它不适用于“=”运算符。我不得不将其更改为“是”。当它是 '=' 时我遇到的错误是“没有为类型 'System.Type' 和 'System.Type' 定义运算符 '='。”
    • @Leah:是的,很抱歉。看起来我应该在写答案时开始更加注意。 TypeOf 可能是一个更简单的选择,至少在代码可读性方面;我也用一个例子更新了答案。
    • 两者之间有一个重要的区别,这就是我写这篇文章的原因。如果对象属于从您检查的类型继承的类,则 TypeOf 检查将返回 True,而 GetType 只有在完全相同的类时才会返回 True。
    • 完全无关紧要的对位:即使 VS CodeAnalysis 抱怨,我仍然觉得参数名称是公共接口的一部分,我的代码中的 PascalCase 也是如此。跨度>
    • 两者有性能差异吗? - 有多个测试用例的Select Case (Obj.GetType()) 与多个IF TypeOf Obj is ... 怎么样?
    【解决方案2】:

    与 Cody Gray 的回复有关的更多细节。由于我花了一些时间来消化它,但它可能对其他人有用。

    首先,一些定义:

    1. 有TypeName,它们是对象、接口等类型的字符串表示形式。例如,BarPublic Class BarDim Foo as Bar 中的TypeName。 TypeNames 可以看作是代码中使用的“标签”,用于告诉编译器在字典中查找哪个类型定义,其中将描述所有可用类型。
    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)

    那么,MyObjObject 类型还是 Integer 类型? MyObj.GetType() 会告诉你这是一个Integer

    1. 但是Type Of Foo Is Bar 功能出现了,它允许您确定变量Foo 与类型名称Bar 兼容。 Type Of MyObj Is IntegerType Of MyObj Is Object 都将返回 True。在大多数情况下,如果变量属于 TypeName 或派生自它的 Type,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) 来获取给定对象的TypeName。例如,

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

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 2011-07-13
      • 1970-01-01
      • 2012-01-03
      • 2011-03-25
      • 1970-01-01
      • 2011-06-07
      • 2017-10-28
      • 2011-09-26
      相关资源
      最近更新 更多