2009-10-14 38 views
13

Tôi đã tự hỏi tại sao C# yêu cầu tôi sử dụng break trong tuyên bố switch mặc dù ngữ nghĩa mùa thu theo định nghĩa không được phép. do đó, trình biên dịch có thể tạo ra các break vào cuối mỗi case -lock và lưu lại cho tôi những rắc rối.Tại sao tôi cần sử dụng ngắt?

Tuy nhiên, có một kịch bản (mà đã được thảo luận trên trang web này) mà tôi có thể đưa ra đó có thể là lý do cho việc sử dụng rõ ràng của break:

switch (foo) { 
    case 0: 
    case 1: 
     bar(); 
     break; 
    default: 
     break; 
} 

Ở đây, phương pháp này bar() được gọi là nếu foo có giá trị 0 hoặc 1.

Tùy chọn này sẽ phá vỡ theo nghĩa xác thực nhất của từ nếu trình biên dịch tự tạo ra các tuyên bố break. Đây có phải là lý do tại sao giờ nghỉ là bắt buộc hay có lý do chính đáng nào khác không?

+7

Cá nhân tôi nghĩ đây là một quyết định thiết kế khủng khiếp của nhóm C# và một trong số ít nơi họ thất bại. –

+0

@Chris: Tôi khuyên bạn nên đọc blog của Eric như được liên kết trong câu trả lời được chấp nhận. Nó giải quyết một vài điều mà tôi đoán là những thứ làm bạn khó chịu. –

+3

Và bạn sẽ làm thế nào, Chris? –

Trả lời

33

Tôi nghi ngờ rằng lý do C# yêu cầu nhà phát triển đặt lệnh ngắt hoặc thiết bị đầu cuối ở cuối mỗi trường hợp là để rõ ràng.

Nó tránh người mới đến ngôn ngữ từ giả định rằng chuyển đổi() trong C# hoạt động như chuyển đổi trong C hoặc C + +, nơi rơi thông qua hành vi xảy ra. Chỉ trong trường hợp các trường hợp trống liền kề xảy ra trong C# - đó là tương đối rõ ràng.

EDIT: Thực ra, trong C# fallthrough luôn là bất hợp pháp. Tuy nhiên, pháp lý là có một trường hợp đơn lẻ được liên kết với hai hoặc nhiều nhãn. Eric Lippert writes at length about this hành vi and how it differs from C/C++ switch statements.

Bạn có thể quan tâm đến việc đọc this article trên blog Eric Lipperts.

+0

+1 cho liên kết tới Eric Lippert, er, blog ;-). Vâng, có thể là sự rõ ràng đã thúc đẩy quyết định thiết kế này. –

+0

Nó cũng cho phép JIT linh hoạt để sắp xếp lại mã để tối ưu hóa mà không đáng lo ngại về việc phá vỡ một cái gì đó do sự sụp đổ. –

+0

@ScottDorman - Không có thông tin thu gọn ... do đó, việc tổ chức lại sẽ không thay đổi bất cứ điều gì nếu giờ nghỉ không cần phải ở đó. Nếu có sự sụp đổ, và việc sắp xếp lại mã có thể gây ra vấn đề, thì giờ nghỉ sẽ không được yêu cầu. – RHSeeger

0

Sự hiểu biết của tôi về vấn đề này là nó được đưa vào để khớp với cú pháp C++.

+6

Hm, nhưng AFAIK C++ không yêu cầu câu lệnh break vì C++ - giống như C - cho phép đối với trường hợp-block để trải qua. –

6

Bằng cách làm phá vỡ không bắt buộc, bạn mở lòng mình lên đến lỗi như thế này:

switch (thing_result) 
{ 
    case GOOD_THING: 
     IssueReward(); 
     // UH-OH, missing break! 
    case BAD_THING: 
     IssuePunishment(); 
     break; 
} 

Các nhà thiết kế ngôn ngữ C# đã cố gắng giúp đỡ các lập trình viên tránh những cạm bẫy trong những ngôn ngữ mà đến trước đó, nói chung bằng cách buộc các lập trình viên để rõ ràng hơn (ví dụ: sử dụng rõ ràng từ khóa 'ghi đè' hoặc 'mới' để triển khai hoặc che giấu các thành viên ảo).

0

Nếu bạn sẽ không cần phải nối thêm một giờ nghỉ, có một vấn đề

switch (number) 
{ 
    case 0: 
    case 1: 
     DoSomething(); 
} 

gì xảy ra nếu số == 0? Đây có phải là một trường hợp rỗng mà không làm bất cứ điều gì hoặc sẽ DoSomething() được thực hiện?

+1

Xin lỗi, nhưng điều đó không đúng. Khi bạn thêm một ngắt sau cuộc gọi DoSomething(), mã C# sẽ hợp lệ và cho cả hai trường hợp, 0 và 1, phương thức DoSomething() sẽ được gọi. –

+1

@RHSeeger, bạn đã sai. – Phong

+0

@Phong, tôi đã xóa nhận xét của mình vì một phần là đúng. Đúng là câu lệnh ngắt chỉ thêm độ dài và không tránh nhầm lẫn. Nhưng nó đã không chính xác trong trường hợp 0 ​​làm gì đó, những gì các trường hợp 1 không ... vì nó chia sẻ cơ thể với 1 trường hợp. – RHSeeger

38

Câu hỏi đặt trước giả định và do đó không thể trả lời được. Ngôn ngữ KHÔNG yêu cầu ngắt ở cuối phần chuyển đổi. Ngôn ngữ yêu cầu danh sách tuyên bố của phần chuyển đổi phải có điểm kết thúc không thể truy cập. "break" chỉ là câu lệnh được sử dụng phổ biến nhất có thuộc tính này. Hoàn toàn hợp pháp để kết thúc phần chuyển đổi có "return;", "goto case 2;", "throw new Exception();" hoặc "while (true) {}" (hoặc trong một số trường hợp, tiếp tục, mặc dù đó thường là ý tưởng tồi.)

Lý do chúng tôi yêu cầu danh sách tuyên bố có điểm cuối không thể truy cập là thực thi quy tắc "không rơi" .

Nếu câu hỏi của bạn được tuyên bố tốt hơn là "tại sao trình biên dịch không tự động sửa lỗi của tôi khi tôi không tạo phần chuyển đổi với danh sách tuyên bố có điểm đến không thể truy cập được, bằng cách chèn tuyên bố giải trình thay cho tôi?" , sau đó câu trả lời là C# không phải là "đoán mò về những gì nhà phát triển có thể có nghĩa là và lộn xộn trên" loại ngôn ngữ. Một số ngôn ngữ là - JScript, ví dụ - nhưng C# thì không.

Chúng tôi tin rằng những người lập trình C# mắc sai lầm muốn được thông báo về những sai lầm đó để họ có thể cố ý và cố tình sửa chúng, và đây là một điều tốt. Khách hàng của chúng tôi cho chúng tôi biết rằng họ không muốn trình biên dịch đoán về ý nghĩa của họ và hy vọng điều tốt nhất. Đó là lý do tại sao C# cũng không đoán về nơi bạn muốn đặt dấu chấm phẩy bị mất, như JScript làm, hoặc âm thầm thất bại khi bạn cố gắng sửa đổi biến chỉ đọc, như JScript làm, v.v.

+4

?? Câu trả lời được chấp nhận đề cập đến blog của Eric và câu trả lời của riêng mình bị giảm bớt? Bình chọn nó lên một lần nữa. – SolutionYogi

+1

Vâng, SolutionYogi, không phải ai cũng đồng ý với tôi. Tôi không có lý do gì để tưởng tượng mọi người sẽ làm; tất cả mọi người được hưởng ý kiến ​​riêng của họ về lý do tại sao ngôn ngữ được thiết kế như nó được. Tôi đánh giá cao cử chỉ, nhưng thực sự, đừng căng thẳng về nó. :) –

+0

Vâng, Eric, tôi đồng ý với bạn 100% và tôi muốn kêu vang với phiếu bầu của tôi để những người khác chú ý đến câu trả lời của bạn! Và tôi không hề căng thẳng về nó. Tôi tôn giáo tuân theo các câu trả lời/nhận xét SO của bạn khi tôi học được rất nhiều từ họ. Bạn không chỉ rất am hiểu, nhưng bạn chia sẻ kiến ​​thức của bạn thông qua văn bản hoàn hảo của bạn. Tôi là một fan hâm mộ lớn của bạn và bất cứ khi nào bạn đang ở NJ/NY, hãy cho tôi biết, tôi muốn mua cho bạn đồ uống/bữa tối! :) – SolutionYogi

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