2010-05-04 63 views
7

Với các nhà điều hành ternary, nó có thể làm điều gì đó giống như Func1 sau (giả sử() và Func2() trả về một int:khai thác ternary trong C#

int x = (x == y) ? Func1() : Func2(); 

Tuy nhiên, có cách nào để làm điều tương tự, mà không trả lại một giá trị Ví dụ, một cái gì đó tương tự (giả sử Func1() và Func2() return void):

(x == y) ? Func1() : Func2(); 

tôi nhận ra điều này có thể được thực hiện bằng một câu lệnh if, tôi chỉ tự hỏi nếu có một cách để làm như thế này.

+1

Xin lỗi để nitpick, nhưng tên thích hợp là toán tử có điều kiện http://msdn.microsoft.com/en-us/library/aa691313(VS.71).aspx –

+6

@Brian: Trong cùng một bài viết, "Nó đôi khi cũng được gọi là toán tử bậc ba ". Vì vậy, thực sự, cả hai đều được sử dụng. –

+4

@Nelson - trong thời trang ký hiệu tổng hợp cũng có thể được gọi là toán tử nhị phân và toán tử tăng dần cũng có thể được gọi là toán tử đơn nguyên? Có ... nhưng nó vẫn không phải là một cách chính xác để đặt tên cho nó, mặc dù thường là nhà điều hành ternary duy nhất được biết đến. (Có câu hỏi hay hơn không.) – ANeves

Trả lời

10

Weird, nhưng bạn có thể làm

class Program 
{ 
    private delegate void F(); 

    static void Main(string[] args) 
    { 
     ((1 == 1) ? new F(f1) : new F(f2))(); 
    } 

    static void f1() 
    { 
     Console.WriteLine("1"); 
    } 

    static void f2() 
    { 
     Console.WriteLine("2"); 
    } 
} 
+1

Đó là rất nhiều công việc phụ để tránh chỉ sử dụng "nếu" và "khác". Đoạn trích đẹp. – GenericTypeTea

+0

Có. Đoạn mã đẹp. – Ram

0

Không, bởi vì toán tử bậc ba là một biểu thức, trong khi các hàm hành động/void là các câu lệnh. Bạn có thể làm cho chúng trở về object, nhưng tôi nghĩ rằng khối if/else sẽ làm cho ý định rõ ràng hơn nhiều (tức là các hành động đang được thực hiện cho tác dụng phụ của chúng thay vì giá trị của chúng).

3

Tôi không nghĩ vậy. Theo như tôi nhớ, toán tử bậc ba được sử dụng trong ngữ cảnh biểu thức và không phải là câu lệnh. Trình biên dịch cần biết loại cho biểu thứcvoid không thực sự là một loại.

Bạn có thể thử để xác định một chức năng cho việc này:

void iif(bool condition, Action a, Action b) 
{ 
    if (condition) a(); else b(); 
} 

Và sau đó bạn có thể gọi nó như thế này:

iif(x > y, Func1, Func2); 

Nhưng điều này không thực sự làm cho mã của bạn bất cứ rõ ràng hơn ...

1

Nếu bạn cảm thấy tự tin, bạn sẽ tạo ra một phương pháp tĩnh có mục đích duy nhất là hấp thụ biểu thức và "làm cho nó" một tuyên bố.

public static class Extension 
{ 
    public static void Do(this Object x) { } 
} 

Bằng cách này bạn có thể gọi toán tử bậc ba và gọi phương thức mở rộng trên đó.

((x == y) ? Func1() : Func2()).Do(); 

Hoặc, theo cách tương đương, hãy viết phương pháp tĩnh (nếu lớp bạn muốn sử dụng lối tắt "này bị giới hạn).

private static void Do(object item){ } 

... và gọi nó theo cách này

Do((x == y) ? Func1() : Func2()); 

Tuy nhiên tôi khuyên bạn nên mạnh mẽ để không sử dụng này "shortcut" cho cùng một lý do đã được thực hiện rõ ràng bởi các tác giả trước mắt tôi.

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