개체가 특정 유형인지 확인하는 방법


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

답변:


160

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 #)를 작성할 때 camelCased (항상 소문자로 시작 함)입니다. 이를 통해 클래스, 유형, 메소드 등을 한 눈에 쉽게 구별 할 수 있습니다.


1
답변 해 주셔서 감사합니다. 나는 그 코드를 시도했지만 실제로 유일한 것은 '='연산자와 함께 작동하지 않는다는 것입니다. 나는 그것을 'Is'로 바꿔야했다. '='일 때 발생한 오류는 " 'System.Type'및 'System.Type'유형에 대해 연산자 '='가 정의되지 않았습니다."였습니다.
Leah

1
@Leah : 네, 죄송합니다. 답을 쓸 때 더주의를 기울여야 할 것 같습니다. TypeOf적어도 코드 가독성 측면에서 더 간단한 옵션 일 것입니다. 그 예를 들어 답변을 업데이트했습니다.
Cody Gray

35
둘 사이에는 중요한 차이점이 있습니다. 이것이 저를이 게시물로 이끌었습니다. TypeOf 검사는 개체가 검사 대상 유형에서 상속 된 클래스 인 경우 True를 반환하는 반면 GetType은 정확히 동일한 클래스 인 경우에만 True를 반환합니다.
Abacus

완전히 사소하고 무관 한 대위법 : VS CodeAnalysis가 불평하더라도 여전히 인수 이름이 공용 인터페이스의 일부라고 생각하고 내 코드에서 PascalCase도 마찬가지입니다.
Mark Hurd

둘 사이에 성능 차이가 있습니까? - Select Case (Obj.GetType())다중 테스트 케이스 대 다중은 IF TypeOf Obj is ...어떻습니까?
Luke T O'Brien

3

Cody Gray의 응답과 관련하여 더 자세한 내용이 있습니다. 소화하는 데 시간이 좀 걸렸기 때문에 다른 사람들에게 유용 할 수도 있지만.

첫째, 몇 가지 정의 :

  1. 객체 유형, 인터페이스 등의 문자열 표현 인 TypeName이 있습니다. 예를 들면 다음과 같습니다. BarPublic Class Bar, 또는에서 TypeName 입니다 Dim Foo as Bar. TypeNames는 사용 가능한 모든 유형이 설명되는 사전에서 어떤 유형 정의를 찾아야하는지 컴파일러에 알리기 위해 코드에서 사용되는 "라벨"로 볼 수 있습니다.
  2. 거기 System.Type에 값을 포함하는 객체. 이 값은 유형을 나타냅니다. 마치 String텍스트 나Int 숫자를 취할 것, 우리가 대신 텍스트 나 숫자의 유형을 저장하는 예외입니다. Type개체에는 유형 정의와 해당 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과 호환되는지 확인할 수 있는 기능이 있습니다 Bar. Type Of MyObj Is Integer그리고 Type Of MyObj Is Object모두 TRUE를 반환합니다. 대부분의 경우 TypeOf는 변수가 TypeName 또는 변수에서 파생 된 Type 인 경우 변수가 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.