オブジェクトが特定のタイプかどうかを確認する方法


102

さまざまなオブジェクトをサブルーチンに渡して同じプロセスを実行していますが、毎回異なるオブジェクトを使用しています。たとえば、ある場合にはListViewを使用し、別の場合にはDropDownListを渡します。

渡されるオブジェクトが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

回答:


159

VB.NETでは、GetTypeメソッドを使用してオブジェクトのインスタンスのタイプを取得し、GetType()演算子を使用して別の既知のタイプのタイプを取得する必要があります。

2つのタイプを取得したら、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#のいずれか)を記述するとき、パラメーターの名前はcamelCased(つまり、常に小文字で始まる)です。これにより、クラス、タイプ、メソッドなどを一目で簡単に区別できます。


1
ご回答有難うございます。私はそのコードを試しましたが、実際には唯一のことは、「=」演算子では機能しないことです。「Is」に変更する必要がありました。'='のときに発生したエラーは、「演算子 '='がタイプ 'System.Type'および 'System.Type'に対して定義されていません。」でした。
Leah

1
@リア:うん、ごめんなさい。答えを書くときはもっと注意を払う必要があるようです。TypeOf少なくともコードの読みやすさの点では、おそらくもっと簡単なオプションです。私もその例で答えを更新しました。
コーディグレイ

35
この2つには重要な違いがあり、それが私をこの投稿に導いた理由です。TypeOfチェックは、オブジェクトがチェック対象の型から継承するクラスのものである場合にTrueを返しますが、GetTypeはそれがまったく同じクラスである場合にのみTrueを返します。
そろばん2013

完全に取るに足らない、無関係な対比: VS CodeAnalysisが不満を言っても、引数名はパブリックインターフェイスの一部であり、PascalCaseも私のコードにあると感じています。
Mark Hurd

2つの間にパフォーマンスの違いはありますか?- Select Case (Obj.GetType())複数のテストケースと複数のテストケースについてはどうIF TypeOf Obj is ...ですか?
ルークTオブライエン

3

Cody Grayからの応答に関連して、もう少し詳しく説明します。それを消化するのに少し時間がかかったので、他の人にとって役に立つかもしれませんが。

まず、いくつかの定義:

  1. TypeNamesがあります。これは、オブジェクト、インターフェイスなどのタイプの文字列表現です。たとえば、やのBarTypeName です。TypeNamesは、コードで使用される「ラベル」と見なすことができ、使用可能なすべての型が記述される辞書で検索する型定義をコンパイラーに指示します。Public Class BarDim Foo as Bar
  2. System.Type値を含むオブジェクトがあります。この値はタイプを示します。がテキストまたは数値の代わりにタイプを格納することを除いて、がテキストまたは数値Stringをとるのと同じようにIntTypeオブジェクトには、型定義とそれに対応するTypeNameが含まれています。

第二に、理論:

  1. Foo.GetType()Type変数の型を含むオブジェクトを返しますFoo。つまり、Fooインスタンスが何であるかがわかります。
  2. GetType(Bar)TypeTypeNameのタイプを含むオブジェクトを返します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と互換性があることを確認できる機能が登場しますBarType Of MyObj Is Integerそして Type Of MyObj Is Object両方のTrueを返します。ほとんどの場合、変数がそのTypeまたはそれから派生した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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.