2012-03-28 17 views
36

Ví dụ:Tại sao một người dùng toán tử | = trên giá trị boolean trong C#?

Chúng tôi thấy đây là một số mã được nhà cung cấp viết và chúng tôi đang cố gắng tìm ra lý do tại sao họ làm điều này.

bool tmp = false; 

if (somecase) 
    tmp = true; 

if (someOtherCase) 
    tmp |= true; 
+17

Phía bên phải có thực sự là một hằng số 'đúng' không? Sử dụng '| =' trên bool là hoàn toàn hợp lý, sử dụng '| = true' hiếm khi là. – CodesInChaos

+3

Bạn biết rằng ngay cả [msdn] (http://msdn.microsoft.com/en-us/library/h5f1zzaw.aspx) liệt kê một toán tử boolean và '| =' trong ví dụ của nó ... –

Trả lời

68

Không có lý do chính đáng nào cả. Giá trị boolean |= true sẽ luôn là true. Đây là người cố gắng ưa thích hoặc quên logic boolean =)

Thay đổi thành tmp = true;.

+0

Cảm ơn bạn sau một vài chương trình thử nghiệm tôi đã đi đến kết luận đó .. đó là lý do tại sao tôi hỏi .. không thể an toàn. – carny666

+8

@ code4life: 'false | true' vẫn là 'true' ... Bạn có quên logic logic của bạn không? –

+1

@ code4life: OK, nếu nó là gì? Sau đó, trạng thái của nó sau "tmp | = true;" là gì? –

2

Kết quả cuối cùng sẽ là "Nếu bất kỳ trường hợp nào là đúng, kết quả sẽ là đúng". Không có lý do gì mà bạn phải sử dụng toán tử mặc dù, vì || trong một if cũng sẽ hoạt động.

+2

Nếu 'someOtherCase' có tác dụng phụ, bạn cần sử dụng' | 'thay vì' || 'để giữ chúng. – phoog

7

Thú vị - trông giống như nó đang làm tương đương với:

tmp = tmp | true; 

Mà sẽ luôn đặt tmp là true.

16

Có lẽ một trong các chữ cái boolean được sử dụng là một biến, và chúng không nghĩ thay đổi toán tử khi chúng thay đổi toán hạng. Rõ ràng logic là tương đương.

Nhiều khả năng, họ đã nghĩ rằng trong trường hợp thứ hai, họ muốn giữ lại kết quả đánh giá điều kiện "nếu" đầu tiên. Tất nhiên, đó là lý do sai lầm.

Một tuyên bố tương đương đơn giản hơn:

bool tmp = somecase | someOtherCase; 

EDIT

Như ghi chú pickypg, tuyên bố này có thể là khó hiểu, vì hầu hết mọi người đều không mong đợi | với các giá trị boolean, và nhiều người sẽ không nhận ra nó hoặc sẽ không nghĩ về các tác động phụ. Cách tốt nhất để được rõ ràng (nếu thực sự có những tác dụng phụ) sẽ là giải pháp của minitech: chỉ cần thay đổi |= thành =.

Hoặc, nếu không có tác dụng phụ nào đối với biểu thức someOtherCase, hãy sử dụng giải pháp của Jakub Konecki: someCase || someOtherCase.

+0

Đó là những gì chúng tôi nghĩ .. hoặc có thể là một loại may mắn-o. – carny666

+1

Tôi nghi ngờ đó là mã ban đầu, nhưng thậm chí phải được chuyển đổi thành 'bool tmp = somecase || someOtherCase; 'để cho ngắn mạch làm công việc của mình. Nếu bạn muốn các tác dụng phụ, thì rất có thể bạn đang phá hủy khả năng đọc bằng một lớp mã, đặc biệt bằng cách kết hợp hoàn toàn hai phương thức chỉ có thể được liên kết lỏng lẻo tại thời điểm đó (vì đầu tiên không ngăn cản thứ hai bằng cách "thất bại" "hoặc bất kỳ' false' đại diện). – pickypg

+0

@pickypg Tôi đồng ý rằng một lớp mã với '|' làm giảm khả năng đọc. Cũng có một cơ hội lớn mà một người nào đó sẽ "sửa" '|' thành '|| 'tại một số điểm. Cả hai đều đúng vì sử dụng '|' với các giá trị boolean không thực sự là thành ngữ C#. Tôi thấy rằng một sự xấu hổ, nhưng không có nhiều việc phải làm. – phoog

0

này tương đương với

tmp = tmp | true; 

EDIT: Đó là bằng

tmp = true; 

Tôi đồng tình với phần còn lại của các áp phích ở đây ...!

Thông tin thêm here

7

foo |= true là một phiên bản ngắn của foo = foo | true.

Mã thực tế có thể được viết lại như

bool tmp = false; 
tmp |= someCase; 
tmp |= someOtherCase; 

Hoặc thậm chí tốt hơn như

someCase || someOtherCase 
+4

Quibble nhỏ: Nếu someOtherCase có tác dụng phụ, 'someCase | someOtherCase' sẽ giữ chúng, trong khi 'someCase || someOtherCase' sẽ không. – phoog

+2

someCase | someOtherCase – phkahler

0

của một biểu thức bằng cách sử dụng | = toán tử gán. Kiểm tra MSDN

+0

Vâng, tôi đã nhìn và hiểu nó chỉ là không có ý nghĩa khi họ sử dụng nó trong mã tôi đã có. – carny666

1

Trình biên dịch thông minh có thể tránh được nhiệm vụ trong trường hợp này, mặc dù nó có thể không phải vì nó không nên ngắn mạch một hoạt động bitwise. Trong mọi trường hợp, nó có vẻ giống như một tối ưu hóa vi mô. Trong thực tế tôi nghi ngờ đó là một mô hình giữ trên tác giả đã sử dụng cờ bit (hoặc s/ông chỉ không hiểu làm thế nào nó hoạt động). Sẽ tốt hơn như:

bool tmp = somecase || someOthercase; 

(và sau đó nội tuyến tạm thời nếu bạn chỉ sử dụng nó một lần)

Lưu ý rằng, khi sử dụng cờ, nó có ý nghĩa.

#define CONDITION_ONE 0x01 
#define CONDITION_TWO 0x02 

int temp = 0; 
if (somecase) { 
    temp = CONDITION_ONE; 
} 

if (someOthercase) { 
    temp |= CONDITION_TWO; 
} 
+0

Điều này không bảo vệ tác dụng phụ của 'someOtherCase', nếu có bất kỳ điều gì cần được bảo tồn. – phoog

+0

@phoog - đó là sự thật. nếu các trường hợp là các hàm hoặc các câu lệnh khác, thì việc sử dụng đánh giá lười biếng sẽ không giống nhau và chúng không nên được kết hợp. – tvanfosson

+0

Bạn có thể kết hợp chúng với toán tử '|'. – phoog

0

cho bools không quá nhiều

tuy nhiên cho bitflags này có thể cho phép mã như thế này:

int flags=0; 
flags|=READ; 
//flags|=UPDATE; 
foo(arg,flags); 

này cho phép một số cờ này bị dễ dàng nhận xét ra (và làm cho lá cờ sử dụng một tad IMO dễ đọc hơn)

4

Giống như các toán tử op = khác, x |= y tương đương (trừ các tác dụng phụ đánh giá nhiều) đến x = x | y. Đây là cách viết ngắn gọn if (!x) x = y; hoặc if (y) x = true;.

Tuy nhiên, không có ý nghĩa gì khi có hằng số ở phía bên phải.

  • x |= true được thẳng thắn hơn viết như x = true
  • x |= falsex không thay đổi.

lý do tại sao họ làm điều này.

Một số giải thích có thể là:

  • Đó là một typo: Họ có nghĩa là để viết tmp = true; thay vì tmp |= true;, nhưng không bao giờ nhận thấy nó bởi vì chương trình của họ đã xảy ra để làm việc như mong đợi.
  • RHS ban đầu là một biến, được thay thế bằng hằng số true mà không thay đổi mã.
  • tmp ban đầu là bitfield (trong đó |= có ý nghĩa hơn), sau này được giảm xuống thành một bit.
Các vấn đề liên quan