วิธีตรวจสอบว่าวัตถุเป็นประเภทใดประเภทหนึ่ง


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

คำตอบ:


161

ใน 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 ที่ไม่สำคัญและไม่เกี่ยวข้องโดยสิ้นเชิง:ตามเนื้อผ้าชื่อของพารามิเตอร์คือ camelCased (ซึ่งหมายความว่าพวกเขาจะขึ้นต้นด้วยตัวอักษรตัวพิมพ์เล็กเสมอ) เมื่อเขียนโค้ด. NET (VB.NET หรือ C #) ทำให้ง่ายต่อการแยกความแตกต่างจากคลาสประเภทวิธีการ ฯลฯ


1
ขอบคุณสำหรับคำตอบ. ฉันลองใช้รหัสนั้น แต่จริงๆแล้วสิ่งเดียวคือมันใช้ไม่ได้กับตัวดำเนินการ '=' ฉันต้องเปลี่ยนเป็น "Is" ข้อผิดพลาดที่ฉันมีเมื่อมันคือ '=' คือ "Operator '=' ไม่ได้กำหนดไว้สำหรับประเภท 'System.Type' และ 'System.Type'
Leah

1
@ ลีอาห์: ใช่ขอโทษด้วย ดูเหมือนว่าฉันควรจะเริ่มใส่ใจมากขึ้นเมื่อเขียนคำตอบ TypeOfอาจเป็นตัวเลือกที่ง่ายกว่าอย่างน้อยก็ในแง่ของการอ่านโค้ด ฉันได้อัปเดตคำตอบพร้อมตัวอย่างเช่นกัน
โคดี้เกรย์

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. มี TypeNames ซึ่งเป็นตัวแทนสตริงของประเภทของวัตถุอินเตอร์เฟซ ฯลฯ ตัวอย่างเช่นที่มีBarเป็น TypeName ในหรือในPublic Class Bar Dim Foo as BarTypeNames อาจถูกมองว่าเป็น "เลเบล" ที่ใช้ในโค้ดเพื่อบอกคอมไพเลอร์ว่าต้องการค้นหานิยามประเภทใดในพจนานุกรมซึ่งจะมีการอธิบายประเภทที่มีอยู่ทั้งหมด
  2. มีSystem.Typeวัตถุที่มีค่า ค่านี้ระบุประเภท เช่นเดียวกับที่Stringจะใช้ข้อความบางส่วนหรือIntจะใช้ตัวเลขยกเว้นเรากำลังจัดเก็บประเภทแทนข้อความหรือตัวเลข Typeออบเจ็กต์มีนิยามประเภทรวมถึง TypeName ที่สอดคล้องกัน

ประการที่สองทฤษฎี:

  1. Foo.GetType()ส่งกลับวัตถุซึ่งมีชนิดสำหรับตัวแปรType Fooกล่าวอีกนัยหนึ่งก็คือจะบอกคุณว่าอะไรFooคือตัวอย่างของ
  2. GetType(Bar)ส่งกลับTypeวัตถุซึ่งมีชนิดสำหรับ BarTypeName
  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เข้ากันได้กับ BarTypeName Type Of MyObj Is Integerและ Type Of MyObj Is Objectทั้งคู่จะคืนค่า True สำหรับกรณีส่วนใหญ่ TypeOf จะระบุว่าตัวแปรเข้ากันได้กับ TypeName ถ้าตัวแปรนั้นเป็น Type นั้นหรือ Type ที่มาจากตัวแปรนั้น ข้อมูลเพิ่มเติมที่นี่: 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.