?: ?? Toán tử thay vì IF | ELSE


85
public string Source
{
    get
    {
        /*
        if ( Source == null ){
            return string . Empty;
        } else {
            return Source;
        }
        */
        return Source ?? string.Empty;
    }
    set
    {
        /*
        if ( Source == null ) {
            Source = string . Empty;
        } else {
            if ( Source == value ) {
                Source = Source;
            } else {
                Source = value;
            }
        }
        */
        Source == value ? Source : value ?? string.Empty;
        RaisePropertyChanged ( "Source" );
    }
}

Tôi có thể sử dụng các ?: ??toán tử CHÍNH XÁC như If / Else không?


Câu hỏi của tôi:
Làm thế nào để viết sau đây với ?: ?? các nhà khai thác

[1]

if ( Source == null ){
    // Return Nothing
} else {
    return Source;
}

[2]

if ( Source == value ){
    // Do Nothing
} else {
    Source = value;
    RaisePropertyChanged ( "Source" );
} 

Tóm lại : Làm thế nào để không làm gì, không trả lại gì và thực hiện nhiều hướng dẫn với ?: ??toán tử?


1
Tuy nhiên, nó sẽ không hoạt động giống nhau. Bằng cách không sử dụng phân nhánh if / else có điều kiện, bạn đang gán lại biến vô điều kiện (và không cần thiết) mỗi khi bạn truy cập nó. Điều đó có thể trở nên tồi tệ rất nhanh, đặc biệt nếu bạn có mã đa luồng. Đừng làm vậy.
Jeff Mercado

1
Bạn sẽ có một lệnh gọi vô tận / đệ quy nếu trình truy cập get của thuộc tính Nguồn đang trả về thuộc tính Nguồn (trình truy cập get của nó).
John K

1
Đoạn mã đầu tiên của bạn có một bộ thu thuộc tính gọi bộ nhận của riêng nó , đến lượt nó, đệ quy gọi bộ nhận của chính nó . Bạn đã để mất tôi ở đó, vì không thể nào thứ như vậy có thể hoạt động trên cánh đồng. Vui lòng tinh chỉnh câu hỏi của bạn và giải thích chính xác những gì bạn muốn đạt được.
Frédéric Hamidi

Trả lại Không có gì? Đó là VB. Bạn đang viết c # ở đây.
Nhiệm vụ

@Task Tôi có nghĩa là làm thế nào để làm như vậy, dòng này là một bình luận cho câu hỏi
Ahmed Ghoneim

Câu trả lời:


198

Đối với [1], bạn không thể: các toán tử này được tạo ra để trả về một giá trị chứ không phải thực hiện các phép toán.

Cách diễn đạt

a ? b : c

đánh giá bnếu alà đúng và đánh giá cnếu alà sai.

Cách diễn đạt

b ?? c

đánh giá bnếu bkhông phải là null và đánh giá cnếu blà null.

Nếu bạn viết

return a ? b : c;

hoặc là

return b ?? c;

họ sẽ luôn trả lại một cái gì đó.

Đối với [2], bạn có thể viết một hàm trả về giá trị phù hợp để thực hiện "nhiều phép toán" của bạn, nhưng điều đó có thể tệ hơn là chỉ sử dụng if/else.


41

Toán tử bậc ba ( ?:) không được thiết kế cho luồng điều khiển , nó chỉ được thiết kế để gán có điều kiện . Nếu bạn cần kiểm soát luồng chương trình của mình, hãy sử dụng cấu trúc điều khiển, chẳng hạn như if/ else.


5
Tôi sẽ nói thêm rằng tôi đã thấy mọi người sử dụng các biểu thức bậc ba lồng nhau thay cho if / else và nó tạo ra mã khó đọc và gỡ lỗi. Mojo xấu xung quanh.
ckramer

4
Đôi khi các toán tử bậc ba lồng nhau tạo ra mã dễ đọc hơn, nếu khoảng trắng được sử dụng đúng cách.
trutheality

2
@truth: Vâng, tôi không có gì chống lại lồng nhau ?:. Nhưng tôi có một vấn đề lớn là chúng được sử dụng cho luồng điều khiển, và đặc biệt là luồng điều khiển lồng nhau !
Oliver Charlesworth

11

Tham chiếu đến?: Toán tử (Tham chiếu C #)

Toán tử điều kiện (? :) trả về một trong hai giá trị tùy thuộc vào giá trị của biểu thức Boolean. Sau đây là cú pháp cho toán tử điều kiện.

Tham khảo ?? Toán tử (Tham chiếu C #)

Các ?? toán tử được gọi là toán tử liên kết null và được sử dụng để xác định giá trị mặc định cho các kiểu giá trị có thể null cũng như các kiểu tham chiếu. Nó trả về toán hạng bên trái nếu nó không phải là null; nếu không nó trả về toán hạng bên phải.

Điều đó có nghĩa là:

[Phần 1]

return source ?? String.Empty;

[Phần 2] không áp dụng ...


3
Điều đó khác với việc không làm gì cả. Nó trả về một chuỗi trống.
trutheality

1
Chắc chắn, nhưng đó không phải là những gì OP yêu cầu. Không phải lỗi của tôi khi OP yêu cầu "không trả lại gì" - bất kể điều đó có thể có nghĩa là gì.
trutheality

1
@trutheality: Không có cơ quan nào nói rằng đó là lỗi của bạn .. Tuy nhiên, OP không muốn trả lại gì và đó là những gì tôi đã cung cấp.
Akram Shahda

3

"Không làm gì" không thực sự hoạt động cho?

if by // Return Không có gì bạn thực sự có nghĩa là trả về null sau đó viết

return Source;

nếu bạn có nghĩa là, bỏ qua codepath rồi viết

 if ( Source != null )
            {
                return Source;
            }
// source is null so continue on.

Và cuối cùng

 if ( Source != value )
            { Source = value;
                RaisePropertyChanged ( "Source" );
            }

// nothing done.

3

Toán tử bậc ba QUAY LẠI một trong hai giá trị. Hoặc, nó có thể thực hiện một trong hai câu lệnh dựa trên tình trạng của nó, nhưng đó thường không phải là một ý kiến ​​hay, vì nó có thể dẫn đến các tác dụng phụ không mong muốn.

bar ? () : baz();

Trong trường hợp này, () không làm gì cả, trong khi baz làm gì đó. Nhưng bạn chỉ làm cho mã kém rõ ràng hơn. Tôi muốn tìm mã dài hơn rõ ràng hơn và dễ bảo trì hơn.

Hơn nữa, điều này có chút ý nghĩa:

var foo = bar ? () : baz();

vì () không có kiểu trả về (nó vô hiệu) và baz có kiểu trả về không xác định tại điểm gọi trong mẫu này. Nếu họ không đồng ý, trình biên dịch sẽ phàn nàn và lớn tiếng.


2

Nếu bạn lo lắng về độ dài dòng mã của mình, tôi sẽ viết điều này thay vì cố gắng lạm dụng các biểu thức.

if (Source == value) return;
Source = value;
RaisePropertyChanged("Source");

Tôi không lạm dụng biểu cảm, tôi chỉ đang suy nghĩ!
Ahmed Ghoneim

1

?: là nhà điều hành hành trình. (tin rằng tôi đã đánh vần đúng) và nó đơn giản để sử dụng. như trong một vị từ boolean? iftrue: ifalse; Nhưng bạn phải có một rvalue / lvalue như trong rvalue = vị từ? iftrue: iffalse;

Ví dụ int i = x < 7 ? x : 7;

nếu x nhỏ hơn 7, tôi sẽ được gán x, nếu không tôi sẽ là 7.

bạn cũng có thể sử dụng nó để đổi lại, như trong return x < 7 ? x : 7;

một lần nữa, như trên, điều này sẽ có ảnh hưởng tương tự.

vì vậy, Source = Source == value ? Source : string.Empty;tôi tin rằng những gì bạn đang cố gắng đạt được thành công.


6
Tôi thích nó. Các nhà khai thác hành trình : nó giúp bạn nhận được từ A đến B ... hoặc từ A đến C ... tùy thuộc vào A.
Rick Sladkey

Đúng, anh ấy có nghĩa là chim ba ba. Nhưng tên chính xác là "có điều kiện".
Erick G. Hagstrom


0

Tôi không nghĩ rằng bạn có thể là một toán tử và giả sử nó trả về cái này hay cái kia. Nó không phải là sự thay thế câu lệnh if else mặc dù nó có thể được sử dụng cho điều đó trong một số trường hợp nhất định.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.