2010-04-06 67 views
22

Tôi có một mảnh đơn giản chút mã được bực bội tôi:C# Nhà điều hành có điều kiện Không phải là tuyên bố?

HashSet<long> groupUIDs = new HashSet<long>(); 
groupUIDs.Add(uid)? unique++ : dupes++; 

Tại thời gian biên dịch, nó tạo ra các lỗi:

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

HashSet.Add được ghi chép lại để trả về một bool, vì vậy ternary (?) nhà điều hành nên hoạt động, và điều này trông giống như một cách hoàn toàn hợp pháp để theo dõi số mục duy nhất và trùng lặp tôi thêm vào bộ băm.

Khi tôi định dạng lại dưới dạng if-then-else, nó hoạt động tốt.

Bất cứ ai có thể giải thích được lỗi và nếu có cách để thực hiện điều này như một toán tử bậc ba đơn giản?

+1

Tôi thích dùng statemnet hơn. Biến giả gán biến mà một số câu trả lời gợi ý chỉ thêm nhầm lẫn. –

+4

Cũng lưu ý ternaries thường được sử dụng để chọn một giá trị, không chọn một hành động. Trong trường hợp của bạn, bạn đang chọn có tăng một trong hai giá trị hay không. Vì vậy, nó có ý nghĩa ngữ nghĩa hơn để sử dụng một if-else vì bạn đang chọn một hành động. – AaronLS

Trả lời

19

Theo thông báo lỗi, toán tử bậc ba không thể được sử dụng làm câu lệnh. Bạn sẽ cần phải làm một cái gì đó như thế này để biến nó thành một bài tập:

int dummy = groupUIDs.Add(uid)? unique++ : dupes++; 

đó đang được nói, tôi khuyên bạn chỉ cần sử dụng if-then-else. Nó ít gây nhầm lẫn vì nó không liên quan đến việc tạo ra các biến giả "ma thuật" ...

+1

sửa nó. Trong C, không có gì sai với một ternary độc lập không làm gì cả. Rõ ràng điều này là không đúng trong C#. Cảm ơn. – abelenky

+9

Hoặc sử dụng if thay vì toán tử bậc ba, thay vì gán giá trị cho biến vô dụng vì mục đích làm mát mã và gây thiệt hại cho khả năng đọc. – ANeves

+1

câu lệnh if được định dạng đầy đủ có 8 dòng với mức thụt lề bổ sung. Điều đó có vẻ như một sự lãng phí rất lớn cho một hoạt động đơn giản như vậy. Tôi cực kỳ thoải mái với ternary như là một lập trình viên C/C++, và không thấy bất kỳ yếu tố mát mẻ nào hoặc làm nó dễ bị tổn thương. – abelenky

4

Trình biên dịch không phàn nàn về Add nó phàn nàn về thực tế là biểu thức điều kiện của bạn không phải là một câu lệnh hoàn chỉnh.

Một số ngôn ngữ (như JavaScript) cho phép bạn sử dụng biểu thức có điều kiện cho logic nhánh như bạn đã làm ở đây nhưng C# yêu cầu bạn gán kết quả của biểu thức điều kiện cho biến. Một khi bạn gán kết quả của biểu thức, bạn đã thực hiện một câu lệnh đầy đủ và trình biên dịch rất vui.

+4

Thực ra, nó phàn nàn về toán tử bậc ba. –

+0

@Andrew Chẳng phải những thứ đó sẽ được coi là số tăng hay không, được đề cập trong thông báo lỗi là một câu lệnh hợp lệ? – AaronLS

+0

@Merhdad - Vâng, bạn nói đúng - tôi đang sửa nó ngay bây giờ. –

7

Bạn không đặt kết quả giá trị của ternary thành bất kỳ thứ gì là lý do tại sao.

HashSet<long> groupUIDs = new HashSet<long>(); 
int count = groupUIDs.Add(uid)? unique++ : dupes++; 
5

Toán tử bậc ba không phải là câu lệnh. Vì vậy, nó không thể được sử dụng một mình trong một hướng dẫn - nó tương đương với việc viết

"something that is not a statement"; 

Để làm rõ, bạn nên dùng toán tử bậc ba và sử dụng if.

+0

Trong C và C++ ít nhất, đó là một tuyên bố hoàn toàn hợp lệ (mặc dù không có tác dụng phụ). Rõ ràng điều này không đúng trong C#. Hóa ra câu trả lời đúng là có một bài tập giả như @sth gợi ý. – abelenky

+0

Đây là một lời giải thích tuyệt vời, bởi vì nếu bạn nghĩ về cách thức hoạt động của một hàm bậc ba, nó sẽ đánh giá một giá trị duy nhất, giá trị được chọn từ hai tùy chọn. Vì vậy, một khi đã đánh giá nó giống như viết câu lệnh đó là giá trị của 'duy nhất;' (sau khi được tăng lên), hoặc 'dupes;' mà sẽ là một cái gì đó giống như '12345;' mà sẽ không phải là một câu lệnh hợp lệ vì nó là chỉ một số nguyên duy nhất. – AaronLS

+1

@AaronLS: Đầu tiên, nó sẽ là giá trị của PRIOR duy nhất để tăng, không phải sau đó. Thứ hai, trong nhiều ngôn ngữ, có một số nguyên đơn là hoàn toàn hợp lệ. C# là khác nhau trong lĩnh vực này. – abelenky

0

Nếu điều này không được chấp nhận, tại sao dòng của bạn lại là? Chỉ cần sử dụng câu lệnh if :-)

 bool b = false; 
     b?callB():callA(); 
1

gmcalab và sr pt là đúng; toán tử bậc ba có nghĩa là cung cấp cho bạn kết quả, giống như 1 + 1 cung cấp cho bạn 2. Bạn không thể chỉ viết:

1 + 1;

Sự nhầm lẫn ở đây (tôi nghĩ) là bạn đang nghĩ đến toán tử bậc ba giống như một hàm.

2

Bạn cần sử dụng giá trị từ toán tử bậc ba cho thứ gì đó ...

HashSet<long> groupUIDs = new HashSet<long>(); 
int newCount = groupUIDs.Add(uid)? unique++ : dupes++; 

hoặc - sử dụng một nếu

HashSet<long> groupUIDs = new HashSet<long>(); 
if (groupUIDs.Add(uid)) 
    unique++; 
else 
    dupes++; 
1

Các description của các nhà điều hành ternary trong tài liệu tham khảo ngôn ngữ nói rằng

If condition is true, first expression is evaluated and becomes the result; if false, the second expression is evaluated and becomes the result.

Dường như ternary chỉ có thể được sử dụng trong bối cảnh của bài tập, mặc dù tham chiếu ngôn ngữ không tuyên bố nó là sự giải thích. Bạn không làm bài tập về kết quả.

Theo ý kiến ​​của tôi, việc viết lại dưới dạng if/else sẽ rõ ràng hơn.

+0

Nó không phải là một nhiệm vụ - bạn có thể chuyển nó sang một phương pháp khác, ví dụ. –

+0

Bạn nói đúng - tôi đã vội vàng và từ ngữ của tôi quá lỏng lẻo. –

16

Như những người khác đã chỉ ra, toán tử điều kiện không phải là biểu thức tuyên bố pháp lý. (Các biểu thức tuyên bố pháp lý là các bài tập, cuộc gọi, số gia, giảm và công trình.)

Tuy nhiên, cũng có vấn đề về phong cách ở đây. Theo tôi, các biểu thức sẽ hữu ích cho các giá trị của chúngsẽ hữu ích cho các tác dụng phụ của chúng. Những gì bạn đang chạy vào là bạn có một biểu thức chỉ hữu ích cho tác dụng phụ của nó, và đó là một mùi mã xấu.

Bạn có tác dụng phụ, vì vậy hãy sử dụng câu lệnh có điều kiện thay vì biểu thức có điều kiện.

+1

Đối với @EricLippert, tôi sẽ thay đổi nó thành câu lệnh có điều kiện, nếu có. Một bước tiến trên đường cong học tập từ C đến C#. – abelenky

+8

@abelenky: Tôi hãnh diện, nhưng làm ơn, đừng làm vì tôi. Làm điều đó vì lợi ích của những người tương lai phải duy trì mã của bạn. :-) –

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