如何检查对象是否为特定类型


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

Answers:


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

完全无关紧要的nitpick:传统上,编写.NET代码(VB.NET或C#)时,参数名称使用驼峰式表示(这意味着它们始终以小写字母开头)。这样一来,他们就可以轻松地与类,类型,方法等一目了然。


1
感谢您的回答。我尝试了该代码,但实际上唯一的事情是它不适用于'='运算符。我必须将其更改为“是”。我遇到的错误是“ =”,是“没有为类型'System.Type'和'System.Type'定义运算符'='。”
Leah

1
@Leah:是的,对此感到抱歉。看起来我在写答案时应该开始更加注意。TypeOf至少在代码可读性方面,这可能是一个更简单的选择;我也用一个例子更新了答案。
科迪·格雷

35
两者之间有一个重要区别,这就是导致我撰写此帖子的原因。如果对象属于从您要检查的类型继承的类,则TypeOf检查将返回True,而如果对象是完全相同的类,则GetType仅将返回True。
算盘

完全无关紧要的对立点:即使VS CodeAnalysis抱怨,我仍然觉得参数名称是公共接口的一部分,而PascalCase在我的代码中也是。
马克·赫德

两者之间在性能上有区别吗?- Select Case (Obj.GetType())多个测试用例与多个比较用IF TypeOf Obj is ...呢?
路加·奥布莱恩

3

有关Cody Gray的回复的更多详细信息。我花了一些时间来消化它,尽管它可能对其他人有用。

首先,一些定义:

  1. 有TypeName,它们是对象,接口等的类型的字符串表示形式。例如,BarPublic Class Bar中或中是TypeName Dim Foo as Bar。TypeNames可以看作是代码中的“标签”,用于告诉编译器要在字典中查找将描述所有可用类型的类型定义。
  2. 有些System.Type对象包含一个值。该值表示类型;就像a String会接受一些文本或a 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还是类型IntegerMyObj.GetType()会告诉你这是一个Integer

  1. 但是此Type Of Foo Is Bar功能来了,它使您可以确定Foo与TypeName兼容的变量BarType Of MyObj Is Integer并且 Type Of MyObj Is Object都将返回True。在大多数情况下,如果变量属于该类型或从其派生的类型,则TypeOf将指示该变量与TypeName兼容。此处的更多信息:https : //docs.microsoft.com/zh-cn/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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.