Cách kiểm tra xem một đối tượng có phải là một loại nhất định hay không


102

Tôi đang chuyển các đối tượng khác nhau vào một chương trình con để chạy cùng một quy trình nhưng mỗi lần sử dụng một đối tượng khác nhau. Ví dụ: trong một trường hợp tôi đang sử dụng ListView và trong một trường hợp khác, tôi đang chuyển một DropDownList.

Tôi muốn kiểm tra xem đối tượng đang được truyền có phải là DropDownList hay không, sau đó thực thi một số mã nếu có. Làm thế nào để tôi làm điều này?

Mã của tôi cho đến nay mà không hoạt động:

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

Câu trả lời:


159

Trong VB.NET, bạn cần sử dụng GetTypephương thức để truy xuất kiểu của một thể hiện của một đối tượng và GetType()toán tử để truy xuất kiểu của một kiểu đã biết khác.

Khi bạn có hai loại, bạn có thể so sánh chúng một cách đơn giản bằng Istoán tử.

Vì vậy, mã của bạn thực sự nên được viết như thế này:

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

Bạn cũng có thể sử dụng TypeOftoán tử thay vì GetTypephương thức. Lưu ý rằng điều này kiểm tra xem đối tượng của bạn có tương thích với loại đã cho, không phải là nó cùng loại. Nó sẽ trông như thế này:

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

End If

Nitpick hoàn toàn tầm thường, không liên quan: Theo truyền thống, tên của các tham số là camelCased (có nghĩa là chúng luôn bắt đầu bằng chữ cái thường) khi viết mã .NET (VB.NET hoặc C #). Điều này giúp chúng dễ dàng phân biệt trong nháy mắt với các lớp, kiểu, phương thức, v.v.


1
Cảm ơn câu trả lời của bạn. Tôi đã thử mã đó nhưng thực sự chỉ có một điều là nó không hoạt động với toán tử '='. Tôi đã phải thay đổi nó thành 'Is'. Lỗi tôi gặp phải khi nó là '=' là "Toán tử '=' không được xác định cho các loại 'System.Type' và 'System.Type'."
Leah

1
@Leah: Vâng, xin lỗi về điều đó. Có vẻ như tôi nên bắt đầu chú ý hơn khi viết câu trả lời. TypeOfcó lẽ là một lựa chọn thậm chí còn đơn giản hơn, ít nhất là về khả năng đọc mã; Tôi cũng đã cập nhật câu trả lời với một ví dụ về điều đó.
Cody Grey

35
Có một sự khác biệt quan trọng giữa cả hai, đó là điều đã dẫn tôi đến bài đăng này. Kiểm tra TypeOf sẽ trả về True nếu đối tượng thuộc một lớp kế thừa từ kiểu bạn đang kiểm tra, trong khi GetType sẽ chỉ trả về True nếu nó chính xác là cùng một lớp.
Abacus

Hoàn toàn tầm thường, quan điểm không liên quan: Mặc dù VS CodeAnalysis phàn nàn, tôi vẫn cảm thấy tên đối số là một phần của giao diện công khai và PascalCase trong mã của tôi cũng vậy.
Mark Hurd

Có sự khác biệt hiệu suất giữa hai? - Thế cònSelect Case (Obj.GetType()) Với nhiều test case Vs nhiều IF TypeOf Obj is ...thì sao?
Luke T O'Brien

3

Một số chi tiết liên quan đến phản hồi từ Cody Grey. Vì tôi đã mất một thời gian để hiểu nó, tôi mặc dù nó có thể hữu ích đối với những người khác.

Đầu tiên, một số định nghĩa:

  1. Có TypeName, là các biểu diễn chuỗi của kiểu đối tượng, giao diện, v.v. Ví dụ, Barlà TypeName trong Public Class Barhoặc trong Dim Foo as Bar. TypeNames có thể được coi là "nhãn" được sử dụng trong mã để cho trình biên dịch biết định nghĩa kiểu nào cần tìm trong từ điển nơi tất cả các kiểu có sẵn sẽ được mô tả.
  2. Có những System.Typeđối tượng chứa một giá trị. Giá trị này cho biết một kiểu; giống như a Stringsẽ nhận một số văn bản hoặc một Intsẽ lấy một số, ngoại trừ chúng tôi đang lưu trữ các loại thay vì văn bản hoặc số. Typecác đối tượng chứa các định nghĩa kiểu, cũng như TypeName tương ứng của nó.

Thứ hai, lý thuyết:

  1. Foo.GetType()trả về một Typeđối tượng chứa kiểu cho biến Foo. Nói cách khác, nó cho bạn biết đâu Foolà một thể hiện của.
  2. GetType(Bar)trả về một Typeđối tượng chứa kiểu cho TypeName Bar.
  3. Trong một số trường hợp, loại một đối tượng là Cast hướng tới khác với kiểu mà một đối tượng được khởi tạo lần đầu tiên. Trong ví dụ sau, MyObj được ghép Integerthành Object:

    Dim MyVal As Integer = 42 Dim MyObj As Object = CType(MyVal, Object)

Vì vậy, là MyObj của loại Objecthoặc của loại Integer? MyObj.GetType()sẽ cho bạn biết nó là một Integer.

  1. Nhưng ở đây có Type Of Foo Is Bartính năng, cho phép bạn xác định một biếnFoo tương thích với TypeName Bar. Type Of MyObj Is IntegerType Of MyObj Is Objectcả hai sẽ trả về True. Đối với hầu hết các trường hợp, TypeOf sẽ chỉ ra một biến tương thích với TypeName nếu biến đó thuộc Loại đó hoặc Loại có nguồn gốc từ nó. Thông tin thêm tại đây: https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/typeof-operator#remarks

Bài kiểm tra dưới đây minh họa khá tốt hành vi và cách sử dụng của từng từ khóa và thuộc tính được đề cập.

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

BIÊN TẬP

Bạn cũng có thể sử dụng Information.TypeName(Object)để lấy TypeName của một đối tượng nhất định. Ví dụ,

Dim Foo as Bar
Dim Result as String
Result = TypeName(Foo)
Debug.Print(Result) 'Will display "Bar"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.