2014-10-17 16 views
22

Đây là một số mã khiến tôi phiền lòng mỗi lần tôi nghĩ về nó.VB vs C#: Tại sao điều này có thể xảy ra?

Option Strict On 

Module Module1 

    Sub Main() 
     For Each i As Integer In New String() {"why", "is", "this", "tolerated?"} 
      ' compiles just fine. 
     Next 
    End Sub 

End Module 

C# đơn giản sẽ không cho phép chuyển đổi chuỗi thành số nguyên một cách ngầm định.

class Program { 
    static void Main(string[] args) { 
     foreach (int i in new string[] {"that's", "better"}) { 
      // will not compile, and for good reason. 
     } 
    } 
} 

Tại sao VB cho phép chúng tôi làm điều đó? Tôi đang cố gắng để vui chơi với điều này bởi vì tôi vẫn còn tương đối mới ở đây, nhưng tôi cũng thực sự tò mò. Tôi chắc rằng có những nhà phát triển ở đó với câu trả lời.

+1

tôi bao gồm các 'Tùy chọn Strict' tuyên bố trong bưu chính, đó là nghĩa vụ để hạn chế chuyển đổi loại để chuyển đổi mở rộng và không cho phép gõ ngầm, tuy nhiên nó vẫn biên dịch. – scottyeatscode

+4

@mellamokb, như OP đã hiển thị, điều này hoạt động ngay cả với 'Tùy chọn Nghiêm ngặt On'. – jmcilhinney

+0

Đó là một điểm tốt. Theo [bài blog này] (http://www.owenpellegrin.com/articles/vb-net/converting-strings-to-numbers/) ngay cả với 'Option Strict Off' nó không nên cho phép chuyển đổi ngầm của chuỗi là không phải là giá trị số hợp lệ, vì vậy một cái gì đó khác phải xảy ra ở đây.** EDIT **: Tôi chỉ cần thử nghiệm này một cách nhanh chóng với LINQPad và nó dường như không biên dịch ... nơi mà bạn đang thử nghiệm này, nơi bạn không nhận được lỗi trình biên dịch? – mellamokb

Trả lời

14

Nó dường như là một phong cách riêng của Tuyên bố For Each. Theo tài liệu, nó được đánh giá tại thời gian chạy.

Từ Link:

Khi Option Strict được thiết lập để Bật, thu hẹp chuyển đổi thường gây ra lỗi biên dịch. Tuy nhiên, trong một câu lệnh For Each, các chuyển đổi từ các phần tử trong nhóm thành phần tử được đánh giá và thực hiện tại thời gian chạy, và các lỗi trình biên dịch gây ra bởi việc thu hẹp chuyển đổi bị loại bỏ.

Trong ví dụ sau, việc gán m làm giá trị ban đầu cho n không biên dịch khi Tùy chọn Strict bật vì chuyển đổi Dài thành số nguyên là một chuyển đổi thu hẹp. Tuy nhiên, trong câu lệnh For Each, không có lỗi trình biên dịch nào được báo cáo, mặc dù việc gán cho số yêu cầu cùng một chuyển đổi từ Long thành Integer. Trong câu lệnh For Each có chứa một số lớn, một lỗi thời gian chạy xảy ra khi ToInteger được áp dụng cho số lớn.

+2

Tuyệt vời! Cảm ơn, Mark! – scottyeatscode

+1

Bạn được chào đón, câu hỏi thú vị. –

+8

Wow - chỉ khi tôi nghĩ rằng tôi muốn nhìn thấy nó tất cả như xa như VB weirdness đi ... –

6

Là một bổ sung cho câu trả lời của Mark, dưới đây là cách biên dịch mã vb.net. Như bạn có thể thấy mã được biên dịch thành câu lệnh For...Next và lỗi chỉ xảy ra vào thời gian chạy khi cố chuyển đổi chuỗi thành số nguyên.

Dim VB$t_array$L0 As String() = New String() { "why", "is", "this", "tolerated?" } 
Dim VB$t_i4$L0 As Integer 
For VB$t_i4$L0 = 0 To VB$t_array$L0.Length - 1 
    Dim i As Integer = Conversions.ToInteger(VB$t_array$L0(VB$t_i4$L0)) 
Next VB$t_i4$L0 
+0

Làm thế nào được bạn có thể xem những gì các mã biến thành như vậy? Tôi không thể làm điều đó trong Reflector 8. – scottyeatscode

+0

Nếu bạn có ứng dụng máy tính để bàn, bạn sẽ có thể kéo và thả tệp thi hành vào cụm treeview. –

+0

Mọi thứ trông rất dễ đọc đối với tôi và trong C#. Đó có phải là sự giải mã sau khi bị làm phiền không? – scottyeatscode

11

Microsoft xin lỗi cho điều này trong các kỹ thuật ngôn ngữ, chương 10.9:

Yếu tố hiện tại của lặp được chuyển thành kiểu của biến điều khiển vòng lặp ngay cả khi chuyển đổi là rõ ràng vì không không có nơi thuận tiện để giới thiệu toán tử chuyển đổi trong câu lệnh. Điều này trở nên đặc biệt rắc rối khi làm việc với loại bộ sưu tập phổ biến nhất, System.Collections.ArrayList, bởi vì kiểu phần tử của nó là Object. Điều này có thể yêu cầu phôi trong nhiều vòng lớn, điều mà chúng tôi cảm thấy không lý tưởng.

Trớ trêu thay, Generics kích hoạt việc tạo ra một bộ sưu tập mạnh mẽ, đánh máy, System.Collections.Generic.List (Of T), mà có thể đã làm cho chúng tôi suy nghĩ lại điểm thiết kế này, nhưng vì lợi ích tương thích, điều này không thể thay đổi ngay bây giờ.

0

Am Tôi là người duy nhất có thể thấy rằng trong các mã VB mảng là một generic (biến thể) mảng trong khi C# mã chứa chuỗi mảng nghiêm ngặt?

+1

Tôi đã cập nhật mã để chúng đều là "mảng chuỗi nghiêm ngặt". Mã vẫn hiển thị không có lỗi thời gian biên dịch. Mark Hall, Bjorn-Roger Kringsja và Hans Passant đã cung cấp đủ thông tin để giải thích tại sao hành vi này xảy ra. – scottyeatscode

+0

Thực tế, nếu bạn nhìn vào câu trả lời của Bjorn-Roger Kringsja, danh sách các chuỗi cuối cùng sẽ trở thành một chuỗi các chuỗi. – scottyeatscode

Các vấn đề liên quan