Sự khác biệt giữa DirectCast () và CType () trong VB.NET


99

Tôi là một lập trình viên C / C ++ / C # có kinh nghiệm, người vừa mới gia nhập VB.NET. Tôi thường sử dụng CType (và CInt, CBool, CStr) cho các phôi vì nó ít ký tự hơn và là cách truyền đầu tiên mà tôi được tiếp xúc, nhưng tôi cũng biết về DirectCast và TryCast.

Đơn giản, có bất kỳ sự khác biệt nào (hiệu ứng của diễn viên, hiệu suất, v.v.) giữa DirectCast và CType không? Tôi hiểu ý tưởng của TryCast.


6
Chính xác lặp lại điều này Đúc kiểu dữ liệu với DirectCast, CType, TryCast stackoverflow.com/questions/2703585/...
MarkJ

1
Có thể có bản sao của kiểu truyền dữ liệu với DirectCast, CType, TryCast
Imad

Câu trả lời:


182

Điều đầu tiên cần lưu ý là VB.NET không có (type)instancecơ chế truyền trực tiếp tương tự với C # . Tôi đưa ra điều này bởi vì nó hữu ích như một điểm khởi đầu trong việc so sánh hai toán tử VB.NET (và chúng là toán tử, không phải hàm, mặc dù chúng có ngữ nghĩa hàm).

DirectCast()nghiêm ngặt hơn toán tử đúc C #. Nó chỉ cho phép bạn truyền khi vật phẩm được truyền đã là loại bạn đang truyền. Tôi tin rằng nó sẽ vẫn mở hộp các loại giá trị, nhưng nếu không nó sẽ không thực hiện bất kỳ chuyển đổi nào. Vì vậy, ví dụ: bạn không thể truyền từ shortđến int, giống như bạn có thể truyền trong C # (int). Nhưng bạn có thể truyền từ một IEnumerablesang một mảng, nếu IEnumerablebiến đối tượng cơ bản của bạn thực sự là một Array. Và tất nhiên bạn có thể ép kiểu từ Objectbất kỳ thứ gì sang bất kỳ thứ gì, giả sử kiểu của cá thể đối tượng của bạn thực sự nằm ở đâu đó bên dưới kiểu ép kiểu của bạn trong cây kế thừa.

Điều này là mong muốn vì nó nhanh hơn nhiều . Có ít chuyển đổi và kiểm tra loại cần diễn ra hơn.

CType()ít nghiêm ngặt hơn toán tử ép kiểu C #. Nó sẽ thực hiện những điều bạn không thể làm với (int)kiểu ép kiểu đơn giản , chẳng hạn như chuyển đổi một chuỗi thành một số nguyên. Nó có nhiều sức mạnh như gọi Convert.To___()trong C #, trong đó ___kiểu đích của diễn viên của bạn.

Điều này là mong muốn bởi vì nó rất mạnh mẽ. Tuy nhiên, sức mạnh này phải trả giá bằng hiệu suất; nó không nhanh bằng DirectCast()hoặc toán tử ép kiểu của C # vì nó có thể cần phải thực hiện khá nhiều việc để hoàn thành quá trình ép kiểu. Nói chung bạn nên thích DirectCast()khi bạn có thể.

Cuối cùng, bạn đã bỏ lỡ một toán tử ép kiểu:, là một toán tử TryCast()tương tự trực tiếp với astoán tử của C # .


23
+1 Tôi muốn nói rằng tính nghiêm ngặt DirectCastlà một lợi thế khác. Nếu bạn mắc lỗi, trình biên dịch sẽ thông báo cho bạn ngay lập tức, nhưng nếu bạn CTypemắc lỗi có thể thỉnh thoảng gây ra hành vi sai trong thời gian chạy - có thể trên một số máy người dùng có cài đặt khu vực khác nhau.
MarkJ

1
Câu trả lời chính xác. Vì vậy, theo thứ tự phức tạp (nhỏ đến lớn): DirectCast, TryCast, CType/ Convert.ToXYZ(), C<xyz>()sẽ có đúng không?
phương châm

3
@motto - đóng. Các "hàm" trong C <xyz> () nên được chuyển lên cao hơn trong danh sách, vì chúng thực sự là toán tử chứ không phải là hàm, mặc dù chúng có ngữ nghĩa hàm. Đối với những kiểu có chúng, chúng rất gần với việc ép kiểu (kiểu) của C #, nhưng sẽ thực hiện thêm một chút công việc.
Joel Coehoorn

3
@MarkJ +1 cho nhận xét của bạn, nhưng lưu ý DirectCastchỉ nghiêm ngặt với các lớp chứ không phải giao diện (vì bạn có thể có các loại COM - và có thể là các loại khác - thực sự triển khai các giao diện không được xác định bởi .GetInterfacesdanh sách của .NET Type ).
Mark Hurd

2
@JoelCoehoorn +1, Nhưng trên thực tế, TryCast()askhông hoàn toàn giống nhau. TryCast()chỉ hoạt động với các kiểu tham chiếu, trong khi ashoạt động với bất kỳ thứ gì có thể là null. Vì vậy, int? icast = myNum as int?;sẽ hoạt động tốt, nhưng Dim icast as Integer? = TryCast(myNum, Integer?)sẽ gây ra lỗi trình biên dịch. Chỉ là một sự khác biệt đặc biệt giữa hai ngôn ngữ. lol
CptRobby

12

Với CTypebạn có thể viết một số điều như thế này Ctype("string",Integer). Nhưng với DirectCastcâu lệnh trên sẽ cho lỗi thời gian biên dịch.

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

0

DirectCasthạn chế hơn CType.

Ví dụ, điều này sẽ tạo ra một lỗi:

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

Nó cũng sẽ được hiển thị trong Visual Studio IDE.

Tuy nhiên, điều này không gây ra lỗi:

Sub Main()
    Dim newint As Integer = CType(3345.34, Integer)
    Console.WriteLine(newint)
    Console.ReadLine()
End Sub
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.