2009-02-18 67 views
23

Có sự khác biệt giữa hai báo cáo:mới IntPtr (0) vs IntPtr.Zero

IntPtr myPtr = new IntPtr(0); 
IntPtr myPtr2 = IntPtr.Zero; 

Tôi đã thấy nhiều mẫu có sử dụng PInvoke rằng thích cú pháp đầu tiên nếu đối số myPtr được gửi bởi ref đến hàm được gọi. Nếu tôi thay thế tất cả IntPtr (0) mới bằng IntPtr.Zero trong ứng dụng của tôi, nó có gây ra bất kỳ thiệt hại nào không?

+0

'IntPtr.Zero' dễ đọc hơn. Tôi nghĩ rằng nó sẽ tốt hơn – user

Trả lời

24

IntPtr là một loại giá trị, vì vậy không giống như String.Empty có tương đối ít lợi ích trong việc có tính chất IntPtr.Zero

tĩnh Ngay sau khi bạn vượt qua IntPtr.Zero bất cứ nơi nào bạn sẽ nhận được một bản sao, vì vậy cho khởi động biến nó làm cho không có sự khác biệt:

IntPtr myPtr = new IntPtr(0); 
IntPtr myPtr2 = IntPtr.Zero; 

//using myPtr or myPtr2 makes no difference 
//you can pass myPtr2 by ref, it's now a copy 

có một ngoại lệ, và đó là so sánh:

if(myPtr != new IntPtr(0)) { 
    //new pointer initialised to check 
} 

if(myPtr != IntPtr.Zero) { 
    //no new pointer needed 
} 

Như một vài áp phích đã nói.

7

Chúng có chức năng tương đương, vì vậy nó sẽ không gây ra vấn đề gì.

IntPtr.Zero đại diện cho trạng thái mặc định của cấu trúc (nó được khai báo nhưng không có hàm tạo nào được sử dụng), do đó giá trị mặc định của intptr (void *) sẽ là rỗng. Tuy nhiên, vì (void *) null và (void *) 0 là tương đương, IntPtr.Zero == new IntPtr (0)

Chỉnh sửa: Trong khi chúng tương đương, tôi khuyên bạn nên sử dụng IntPtr.Zero để so sánh nó đơn giản là dễ đọc hơn.

+0

Đó là những gì tôi nghĩ quá ... :) Vậy tại sao có khoảng một triệu mẫu trên web sử dụng IntPtr mới (0)? Không phải là nó tốt hơn để sử dụng phiên bản biến tĩnh? –

-2

Chủ yếu là đóng gói vật chất (và hiệu suất, nhưng ở mức độ thấp hơn nhiều). Tại một thời điểm nào đó trong tương lai, Microsoft có thể quyết định (mặc dù rất khó xảy ra) rằng giá trị con trỏ được đơn vị hóa từ bây giờ sẽ bằng 0xDEADBEEF, do đó hiển thị tất cả mã new IntPtr(0) không hợp lệ.

Theo như hiệu suất là có liên quan, MSDN nói điều này:

Ví dụ, giả sử biến, ip, là một thể hiện của IntPtr. Bạn có thể xác định nếu nó đã được thiết lập bằng cách so sánh nó với giá trị được trả về bởi một hàm tạo, ví dụ: "if ip! = New IntPtr (0) ...". Tuy nhiên, việc gọi một hàm tạo để nhận con trỏ không được định nghĩa là không hiệu quả. Tốt hơn là viết mã "if ip != IntPtr.Zero..." hoặc "if !IntPtr.Zero.Equals(ip)...".

+0

-1: Đoạn đầu tiên không chính xác. new IntPtr (0) không tạo ra một IntPtr chưa được khởi tạo; nó tạo ra một cái được khởi tạo rõ ràng bằng không. Cũng như IntPtr.Zero. Cả hai đều hoàn toàn giống hệt về mặt ngữ nghĩa. –

+0

Vấn đề là IntPtr.Zero có thể được thay đổi bằng một thứ khác không phải là không phá vỡ bất kỳ mã của bên thứ ba nào. –

+0

Không, không thể. Nó là một IntPtr với một giá trị bằng không, như tên cho biết. Từ MSDN: "Một trường chỉ đọc đại diện cho một con trỏ hoặc xử lý đã được khởi tạo bằng không." (http://msdn.microsoft.com/en-us/library/system.intptr.zero.aspx) –

5

Việc sử dụng IntPtr.Zero sẽ cho phép bạn tránh trường hợp mới IntPtr.

từ msdn:

Sử dụng lĩnh vực này để có hiệu quả xác định xem một thể hiện của IntPtr đã được thiết lập một giá trị khác hơn không

+0

đúng, nhưng trong đó không áp dụng cho một trong các trường hợp OP đề cập đến. –

1

gì xảy ra nếu bạn vượt qua IntPtr.Zero bởi ref và người nhận cố gắng sửa đổi tham chiếu? Từ thời điểm đó, sẽ IntPtr.Zero != new IntPtr(0), hoặc người nhận sẽ nhận được một số loại ngoại lệ khi cố gắng thực hiện thay đổi?

Tôi không chắc chắn về điều này, nhưng nó có vẻ giống như một lời giải thích hợp lý.

+0

Bạn không thể chuyển trường chỉ đọc dưới dạng tham số ref. –

+0

Đó là điều tôi sợ ... Nhưng tôi nghĩ điều đó không xảy ra. Bởi vì tôi không thực sự gửi IntPtr.Zero bởi ref. Tôi có thể gửi một boxing của myPtr. Nhưng tôi không thực sự chắc chắn về nó hoặc là ... Do đó câu hỏi của tôi ... :) –

+1

Nếu bạn gán IntPtr.Zero cho một biến trước khi chuyển nó sang phương pháp khác của bạn, bạn không phải là đi qua IntPtr.Zero nhưng một bản sao cục bộ (đó là một cấu trúc). –

0

JITter có thể nội dòng IntPtr.Zero giống như cách nó mô tả IntPtr.Size.

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