2012-03-08 6 views
9

Làm cách nào để sử dụng điều kiện số ? : ternary để thực hiện nhiều thao tác, nếu biểu thức là đúng/sai?Sử dụng toán tử bậc ba cho nhiều thao tác

wbsource = (exp) ? (Do one thing) : (Do second thing) wbsource = (exp) ? (Do one thing) (Do second thing) : (Do second thing)

Đối với ví dụ:

Tại sao tôi không thể thực hiện ba hoạt động giữa ?:

filename = (fp!=null) ? fp; Properties.Settings.Default.filename=fp; Properties.Settings.Default.Save; : Properties.Settings.Default.file; 

Với đơn giản nếu điều kiện, tôi sẽ có văn bản một cách đơn giản như:

if(fp!null) 
{ 
filename = fp; 
Properties.Settings.Default.filename; 
Properties.Settings.Default.Save(); 
} 
else 
{ 
filename = Properties.Settings.Default.file 
} 

Cách viết ngắn gọn bằng cách sử dụng toán tử ternary ở trên là gì?

+1

Tôi thích cách if/else trong trường hợp này - dễ đọc hơn nhiều IMHO ... – assylias

+3

Unary có nghĩa là "với một toán hạng". '? : 'has * ba * toán hạng - đó là toán tử * ternary * và tên của nó là toán tử điều kiện. –

Trả lời

14

Tại sao tôi không thể thực hiện ba hoạt động giữa? và:

Bởi vì đây là những toán hạng, đó là biểu. Mỗi biểu thức đánh giá một giá trị; bạn muốn có nhiều câu lệnh . Từ số điện thoại blog post about foreach vs ForEach của Eric Lippert:

Lý do đầu tiên là vi phạm nguyên tắc lập trình chức năng mà tất cả các nhà khai thác chuỗi khác dựa vào. Rõ ràng mục đích duy nhất của một cuộc gọi đến phương pháp này là gây ra tác dụng phụ.

Mục đích của biểu thức là tính giá trị, không gây ra tác dụng phụ. Mục đích của một tuyên bố là gây ra một tác dụng phụ. Trang web cuộc gọi của điều này sẽ trông rất khủng khiếp như một biểu thức (mặc dù, phải thừa nhận rằng, vì phương thức này là void-return, biểu thức chỉ có thể được sử dụng trong ngữ cảnh "biểu thức câu lệnh")

Bạn nên hoàn toàn viết điều này bằng cách sử dụng khối if. Nó rõ ràng hơn.

Nếu bạn thực sự, thực sự muốn sử dụng các nhà điều hành có điều kiện cho điều này, bạn có thể viết:

// Please, please don't use this. 
Func<string> x =() => { 
    Properties.Settings.Default.filename = fp; 
    Properties.Settings.Default.Save(); 
    return fp; 
}; 

string filename = fp == null ? Properties.Settings.Default.file : x(); 
+1

Tại sao không khai báo chức năng ẩn danh nội tuyến (trò đùa) – Jodrell

2

Nếu bạn thực sự, thực sự muốn, bạn có thể sử dụng một chức năng trong đó có side effects:

filename = (fp!=null) ? DoOneThing(...) : DoAnotherThing(...); 

Mặc dù bất kỳ ai duy trì mã của bạn sẽ không cảm ơn bạn.

3

Toán tử điều kiện, là toán tử bậc ba (không phải là toán tử đơn nguyên), không thay thế cho câu lệnh if. Nó là một toán tử trả về một trong hai kết quả. Mặc dù bạn có thể liên kết chuỗi này đến một mức độ nào đó:

var result = someBool ? "a" : (otherBool ? "b" : "c"); 

Điều đó hơi khó đọc. Hơn nữa, bạn đang cố gắng gọi hàm Save(), không trả lại kết quả, do đó bạn không thể sử dụng nó với toán tử này.

1

Câu trả lời ngắn gọn, sử dụng khối if, đó là điều lành mạnh duy nhất cần thực hiện.

Câu trả lời khác, dành cho cá nhân điên rồ, có mùi hôi.

filename = (fp!=null) ? Func<string> {fp = Properties.Settings.Default.filename; Properties.Settings.Default.Save; return fp;} : Properties.Settings.Default.file; 
2

Nếu đây là c bạn muốn được OK nhờ vào "comma operator":

int b; 
int a = (1==1) ? (b=6, somemethod(), 1) : (b=7, 2); 

Đây b sẽ được thiết lập đến 6, somemethod sẽ được gọi và sau đó a được thiết lập để 1.

Rất may là một tính năng không được chuyển sang, sử dụng if..else nó rõ ràng hơn nhiều.