2012-09-19 34 views
12

Nó có thể là một câu hỏi dễ dàng và đơn giản nhưng tôi vẫn còn có một chút nhầm lẫn lý do tại sao bitwise OR được quyết định sử dụng. Giả sử tôi có một lớp A với bốn lĩnh vực:Tại sao bitwise OR toán tử được sử dụng trong cờ enum với ý nghĩa VÀ

class A 
{ 
    private int Field1; 
    private static int Field2; 
    public int Field3; 
    public static int Field4; 
} 

Và sử dụng Reflection để có được các lĩnh vực:

var fields = typeof (A).GetFields(BindingFlags.Public | BindingFlags.Static); 

Nếu bạn là newbie với Reflection và không biết cách làm thế nào để sử dụng BindingFlags, các suy nghĩ logic ban đầu trong đầu của bạn sẽ là:

Dòng này sẽ chọn tất cả các trường công khai OR tĩnh vì bitwise OR được sử dụng. Và dự kiến ​​kết quả mà bạn nghĩ:

Field2 
Field3 
Field4 

Nhưng khi nhấn F5, kết quả sẽ hoàn toàn khác nhau, Bitwise OR công trình như AND:

Field4 

Tại sao không sử dụng phép toán AND điều hành mà có thể làm theo với suy nghĩ logic. như thế này:

var fields = typeof (A).GetFields(BindingFlags.Public & BindingFlags.Static); 

tôi thấy từ trong MSDN:

các Bitwise OR dùng để kết hợp những lá cờ có thể được coi là một khái niệm tiên tiến trong một số trường hợp không nên được yêu cầu cho các nhiệm vụ đơn giản.

Bất cứ ai có thể giải thích khái niệm trước trước ở đây theo cách đơn giản để hiểu?

+1

'OR' có vẻ là khái niệm đúng ở đây khi bạn xem xét sự khác biệt giữa OR bao gồm và độc quyền. Trong trường hợp này, 'OR' được bao gồm, giống như nói" nhặt cho tôi một số vật phẩm từ cửa hàng chứa trứng hoặc giăm bông ". Đó là khác với nói "có chứa trứng VÀ ham". –

+0

trong [MSDN] (http://msdn.microsoft.com/en-us/library/6ztex2dc.aspx) bạn đã đọc: Bạn phải chỉ định BindingFlags.Instance ** hoặc ** BindingFlags.Static để nhận được trả lại . Vì vậy, có thể bạn không thể liệt kê dụ ** và ** tĩnh cùng một lúc ... ?? – tschmit007

+0

@ tschmit007: Điều đó có liên quan gì đến câu hỏi này? –

Trả lời

25

Xem kết thúc để có tóm tắt ngắn.

Long trả lời:

Bitwise OR được kết hợp các bit của cờ enum.

Ví dụ:

  • BindingFlags.Public có giá trị của 16 hoặc 10000 (nhị phân)
  • BindingFlags.Static có giá trị của 8 hoặc 1000 (nhị phân)

Bitwise OR kết hợp các giống như sau :

10000 
01000 
-- 
11000 --> 24 

bitwise VÀ sẽ kết hợp chúng thích e này:

10000 
01000 
-- 
00000 --> 0 

Đó là một khái niệm rất cơ bản của Flags:
Mỗi giá trị là một sức mạnh của hai, ví dụ:

  • 1 = 2^0
  • 2 = 2^1
  • 4 = 2^2
  • 8 = 2^3
  • , vv

đại diện chút của họ luôn luôn là một 1 và phần còn lại số không :

decimal | binary 
1  | 0001 
2  | 0010 
4  | 0100 
8  | 1000 

Kết hợp bất kỳ trong số chúng bằng bitwise VÀ sẽ luôn dẫn đến 0 vì không có 1 ở cùng một vị trí. Bitwise AND sẽ dẫn đến mất thông tin đầy đủ.

Bitwise HOẶC mặt khác sẽ luôn dẫn đến kết quả rõ ràng. Ví dụ, khi bạn có (nhị phân) 1010 (thập phân 10) bạn biết nó ban đầu là 8 và 2. Không có khả năng nào khác 10 có thể được tạo ra.
Như Mặc định nói, phương pháp mà bạn gọi là sau này có thể trích xuất thông tin này bằng cách sử dụng toán tử AND điều hành:

if(10 & 8 == 8) // value 8 was set 

Các Bitwise OR trong trường hợp này về cơ bản là một phương tiện để vận chuyển các giá trị vào phương pháp bạn đang gọi.
Phương pháp này thực hiện với những giá trị này không liên quan gì đến việc sử dụng bitwise HOẶC.
Nội bộ có thể yêu cầu TẤT CẢ các cờ được thông qua để khớp với trường hợp là GetFields. Nhưng nó cũng có thể yêu cầu chỉ một trong những lá cờ được thông qua để phù hợp.

Đối với bạn như một người gọi, sau đây sẽ tương đương:

var requiredFlags = new List<BindingFlags>(); 
requiredFlags.Add(BindingFlags.Public); 
requiredFlags.Add(BindingFlags.Static); 
typeof (A).GetFields(requiredFlags); 

Bây giờ điều đó không có biên dịch như GetFields không cung cấp như một tình trạng quá tải, nhưng ý nghĩa sẽ là giống như của bạn mã.

Tổng hợp những thứ lên (TL; DR):

Bitwise AND không có gì để làm với Boolean AND
Bitwise OR có gì để làm với Boolean OR

+1

mà ** sau ** sẽ được sử dụng với toán tử '&' như 'if (userArgument & BindingFlags.Public) {/ * thêm vào giá trị trả về * /}' – Default

2

Các enum cờ đang được sử dụng đại diện cho một tập hợp các điều kiện boolean.

Trong ví dụ của bạn, mỗi điều kiện boolean phải được đáp ứng cho trường tương ứng được trả về.

Cờ enums chỉ đơn giản là giá trị tích phân tuân theo các quy tắc nhị phân thông thường cho anding và oring, do đó, để đặt một số bit, bạn phải HOẶC cùng nhau các giá trị đại diện cho các bit đó.

Một khi bạn đã làm như vậy, bạn có một lá cờ enum với bộ bit thích hợp.

Sự cố bạn đang gặp là vì bạn đang tạo hai khái niệm khác nhau: Cách bạn xây dựng bộ điều kiện boolean cho cờ enum là một khái niệm. Cách mà enum cờ được sử dụng (hoặc những gì nó đại diện) là một khái niệm khác nhau.

Sử dụng OR trước đây để xây dựng bộ điều kiện boolean. Sau này nói rằng mỗi bit đại diện cho một điều kiện boolean phải được đáp ứng.

1

Những người triển khai GetFields() đã chọn giải thích kết hợp các cờ ORed khác nhau có nghĩa là kết hợp AND của tiêu chí đã chọn.

Điều này có ý nghĩa vì bạn luôn có thể xóa tiêu chí nếu bạn không muốn bộ lọc bổ sung.

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