2011-01-19 37 views
5

tôi thấy đoạn mã này trên SO (xin lỗi tôi không có liên kết đến các combo câu hỏi/câu trả lời)Toán tử C# này hoạt động như thế nào trong đoạn mã này?

bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) == FileAttributes.Directory; 

này confuses me vì FileAttributes.Directory là trên cả hai mặt của ==.

& làm gì trong trường hợp này? Tôi không chắc cách đọc dòng mã này. Tôi đang cố gắng để đánh giá liệu một chuỗi đường dẫn là một tập tin hoặc một thư mục.

Trả lời

5

Đang sử dụng mặt nạ bit để kiểm tra xem một bit (FileAttributes.Directory) có được đặt hay không.

Giá trị của enum là lũy thừa của hai, tương ứng với từng bit riêng lẻ.

ReadOnly = 1, 
    Hidden = 2, 
    System = 4, 
    Directory = 16, 
    Archive = 32, 
    Device = 64, 

Nếu ReadOnly và thư mục được thiết lập sau đó FileAttributes bằng 17. Việc tính toán sẽ như thế này trong hệ nhị phân:

File.GetAttributes(source) = 00001001 
FileAttributes.Directory = 00001000 & 
------------------------------------- 
          00001000 

Nếu bit thư mục đã không bộ bạn sẽ nhận được không thay :

File.GetAttributes(source) = 00000001 
FileAttributes.Directory = 00001000 & 
------------------------------------- 
          00000000 

Cách viết ngắn gọn hơn mang lại hiệu quả tương tự là thử nghiệm với số không:

bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) != 0; 
+0

Tôi không chắc chắn cách C++ xử lý boolean, nhưng ANSI C cũng sẽ cho phép hơi ngắn hơn: bool isDir = (File.GetAttributes (source) & FileAttributes.Directory); – oosterwal

5

hoạt động của bitwise AND. Các thuộc tính được lưu trữ dưới dạng các cờ bit, do đó, nó là các cờ đó cùng với AttributeFlags.Directory để xem một trong các thuộc tính có phải là .Directory.

Tốt ví dụ về Bit Flags ở đây: http://weblogs.asp.net/wim/archive/2004/04/07/109095.aspx

[Flags] 
public enum FileAttributes 
{ 
    Archive,  // 0000 
    Compressed,  // 0001 
    Device,   // 0010 
    Directory,  // 0100 
    Encrypted,  // 1000 
    ... 
} 

Sau đó:

File.GetAttributes(source): 1101 
FileAttributes.Directory: 0100 
(Logical AND):    0100 

0100 cũng giống như cờ thư mục, vì vậy bây giờ chúng ta biết rằng lá cờ đó là trong những lá cờ được chọn của enum.

1

& trong trường hợp này là nhà điều hành bitwise and.

2

Đây là logical & operator. Trong ví dụ cụ thể này, nó sẽ kiểm tra nếu kiểu liệt kê FileAttributes có giá trị Thư mục, xác minh xem chuỗi được trỏ bởi biến số source là một thư mục hay không.

0

Đó là hoạt động bitwise AND. FileAttributes là Cờ enum. Điều đó có nghĩa là mỗi bit trong giá trị số của enum này mô tả một số thuộc tính boolean của tệp này và chúng có thể được kết hợp.

1

Đang thực hiện kiểm tra cờ bitwise - File.GetAttributes(source) có thể trả lại số số cờ (trong các bit khác nhau) cho biết các thuộc tính khác nhau. Các & hạn chế các 1 s đến chỉ những thứ có trong FileAttributes.Directory (Tôi hy vọng đây là một bit). Khi nó xảy ra, đây là 16, tức là (nhị phân) ..0001000

nếu sourceReadOnly (= 1), Hidden (= 2) và Directory (= 16), nó sẽ là:

...0001011 

chúng tôi & với 16

...0001000 

rời

...0001000 

do đó kiểm tra thư mục vượt qua.

Nếu thay nguồn có System (= 4) và ReadOnly (= 1) (và không phải thư mục) nó sẽ là:

...0000101 

chúng tôi & với 16

...0001000 

rời

...0000000 

do đó kiểm tra thư mục không thành công.

Là một lưu ý phụ; một == trong thử nghiệm như vậy xác minh rằng tất cả cờ bắt buộc được đặt (nếu có nhiều bit trong toán hạng thứ hai). Một thử nghiệm phổ biến khác là != 0, kiểm tra xem có bất kỳ bit nào không.

0

Nó đang kiểm tra xem cờ FileAttributes.Directory được đặt trong enum được trả lại bởi File.GetAttributes. Bạn có thể đọc thêm về cách sử dụng cờ enums trong this entry on MSDN.

Tôi đang cố gắng đánh giá xem chuỗi đường dẫn là tệp hay thư mục.

Tôi muốn sử dụng một trong những phương pháp trong System.IO, như Directory.Exists:

if (Directory.Exists(path)) 
{ 
    // it's a directory 
} 
else if (File.Exists(path)) 
{ 
    // it's a file 
} 
else 
{ 
    // doesn't exist 
} 
0

GetAttributes trả về một giá trị cờ, nơi mà mỗi bit đại diện cho một nhà nước Boolean khác nhau. Mã này sử dụng toán tử bitwise &, để bật cờ Thư mục, ngoài bất kỳ cờ nào khác được trả về bởi GetAttributes.

Điều này dường như quá phức tạp. Đây là tương đương với văn bản:

bool isDir = File.GetAttributes(source).HasFlag(FileAttributes.Directory); 

Hoặc, để kiểm tra độc quyền cho thuộc tính Thư mục:

The() phương pháp HasFlag hiện là một chút chậm, do đó, một thay thế Bitwise là nhanh hơn và sử dụng ít tài nguyên. HasFlag là tốt đẹp để nhận được một phản ứng nhanh chóng và dễ dàng cho dù bit mong muốn trong cờ là hoặc tắt, mà không có bất kỳ kiến ​​thức về các giá trị bit hoặc nhị phân nói chung.

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