ความแตกต่างระหว่าง DirectCast () และ CType () ใน VB.NET


102

ฉันเป็นโปรแกรมเมอร์ C / C ++ / C # ที่มีประสบการณ์ซึ่งเพิ่งเข้าสู่ VB.NET โดยทั่วไปฉันใช้ CType (และ CInt, CBool, CStr) สำหรับการแคสต์เนื่องจากมีอักขระน้อยกว่าและเป็นวิธีแรกในการแคสต์ที่ฉันได้สัมผัส แต่ฉันก็รู้จัก DirectCast และ TryCast ด้วย

เพียงแค่มีความแตกต่างกัน (ผลของการร่าย, ประสิทธิภาพ ฯลฯ ) ระหว่าง DirectCast และ CType หรือไม่? ฉันเข้าใจความคิดของ TryCast


6
สำเนาของCasting DataTypes นี้อย่างแน่นอนกับ DirectCast, CType, TryCast stackoverflow.com/questions/2703585/…
MarkJ

1
อาจซ้ำกันของCasting DataTypes กับ DirectCast, CType, TryCast
Imad

คำตอบ:


184

สิ่งแรกที่ควรทราบคือ VB.NET ไม่มี(type)instanceกลไกการหล่อแบบอะนาล็อกโดยตรงกับ C # ฉันนำสิ่งนี้มาใช้เนื่องจากมีประโยชน์เป็นจุดเริ่มต้นในการเปรียบเทียบตัวดำเนินการ VB.NET สองตัว (และเป็นตัวดำเนินการไม่ใช่ฟังก์ชันแม้ว่าจะมีความหมายของฟังก์ชันก็ตาม)

DirectCast()เข้มงวดกว่าตัวดำเนินการหล่อ C # อนุญาตให้คุณร่ายได้ก็ต่อเมื่อไอเทมที่กำลังร่ายอยู่นั้นเป็นประเภทที่คุณกำลังร่าย ฉันเชื่อว่ามันจะยังคงยกเลิกการใช้งานประเภทค่า แต่ไม่เช่นนั้นจะไม่ทำการแปลงใด ๆ ดังนั้นสำหรับตัวอย่างเช่นคุณจะไม่สามารถส่งจากshortไปintเช่นคุณสามารถด้วย C # (int)หล่อ แต่คุณสามารถส่งจากIEnumerableอาร์เรย์ได้หากIEnumerableตัวแปรออบเจ็กต์พื้นฐานของคุณเป็นArrayไฟล์. และแน่นอนว่าคุณสามารถร่ายจากObjectอะไรก็ได้โดยสมมติว่าประเภทของอินสแตนซ์วัตถุของคุณอยู่ที่ไหนสักแห่งที่ต่ำกว่าประเภทการร่ายของคุณในแผนผังการสืบทอด

นี่เป็นที่พึงปรารถนาเพราะเร็วกว่ามาก มีการตรวจสอบ Conversion และประเภทน้อยกว่าที่จำเป็นต้องเกิดขึ้น

CType()เข้มงวดน้อยกว่าตัวดำเนินการหล่อ C # มันจะทำสิ่งที่คุณไม่สามารถทำได้ด้วยการ(int)ร่ายแบบธรรมดาเช่นการแปลงสตริงเป็นจำนวนเต็ม มันมีพลังมากพอ ๆ กับการเรียกConvert.To___()ใน C # ซึ่ง___เป็นประเภทเป้าหมายของการร่ายของคุณ

สิ่งนี้เป็นที่พึงปรารถนาเพราะมีพลังมาก อย่างไรก็ตามพลังนี้มาพร้อมกับต้นทุนของประสิทธิภาพ มันไม่เร็วเท่าDirectCast()หรือตัวดำเนินการแคสต์ของ C # เพราะอาจต้องทำงานค่อนข้างมากในการแคสต์ให้เสร็จ โดยทั่วไปคุณควรเลือกDirectCast()เมื่อทำได้

สุดท้ายคุณพลาดหนึ่งในผู้ประกอบการหล่อ: TryCast()ซึ่งเป็นอะนาล็อกโดยตรงกับ C # 's asผู้ประกอบการ


24
+1 ฉันจะบอกว่าความเข้มงวดDirectCastเป็นข้อดีอีกอย่าง หากคุณทำผิดพลาดคอมไพเลอร์จะแจ้งให้คุณทราบทันที แต่หากCTypeเกิดความผิดพลาดอาจทำให้เกิดพฤติกรรมผิดพลาดในบางครั้งในขณะทำงาน - อาจเกิดขึ้นกับเครื่องผู้ใช้บางเครื่องที่มีการตั้งค่าภูมิภาคที่แตกต่างกัน
MarkJ

1
คำตอบที่ดี ดังนั้นเพื่อความซับซ้อน (ขนาดเล็กไปจนถึงขนาดใหญ่): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()จะถูกต้องหรือไม่
คำขวัญ

3
@motto - ปิด. C <xyz> () "ฟังก์ชัน" ควรถูกย้ายให้สูงขึ้นในรายการเนื่องจากเป็นตัวดำเนินการแทนที่จะเป็นฟังก์ชันแม้ว่าจะมีความหมายของฟังก์ชันก็ตาม สำหรับประเภทที่มีพวกเขามีความใกล้เคียงกับการหล่อของ C # แต่จะทำงานได้มากขึ้นเล็กน้อย
Joel Coehoorn

3
@MarkJ +1 สำหรับความคิดเห็นของคุณ แต่หมายเหตุDirectCastจะเข้มงวดเฉพาะกับคลาสเท่านั้นไม่ใช่อินเทอร์เฟซ (เนื่องจากคุณสามารถมีประเภท COM - และอาจเป็นแบบอื่นที่ใช้อินเทอร์เฟซที่ไม่ได้กำหนดโดยรายการประเภท. NET .GetInterfaces)
Mark Hurd

2
@JoelCoehoorn +1 แต่จริงๆแล้วTryCast()และasไม่ได้เหมือนกัน TryCast()ใช้งานได้กับประเภทการอ้างอิงเท่านั้นในขณะที่asใช้ได้กับทุกสิ่งที่เป็นโมฆะ ดังนั้นint? icast = myNum as int?;จะทำงานได้ดี แต่Dim icast as Integer? = TryCast(myNum, Integer?)จะให้ข้อผิดพลาดของคอมไพเลอร์ อีกหนึ่งความแตกต่างที่แปลกประหลาดระหว่างสองภาษา lol
CptRobby

12

ด้วยคุณสามารถเขียนบางสิ่งบางอย่างเช่นนี้CType Ctype("string",Integer)แต่ด้วยDirectCastข้อความข้างต้นจะทำให้เวลาคอมไพล์ผิดพลาด

 Dim a As Integer = DirectCast("1", Integer) 'Gives compiler error
 Dim b As Integer = CType("1", Integer) 'Will compile

0

DirectCastเป็นข้อ จำกัด CTypeมากกว่า

ตัวอย่างเช่นสิ่งนี้จะทำให้เกิดข้อผิดพลาด:

Sub Main()
    Dim newint As Integer = DirectCast(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub

นอกจากนี้ยังจะแสดงใน Visual Studio IDE

อย่างไรก็ตามสิ่งนี้ไม่ทำให้เกิดข้อผิดพลาด:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.