новый IntPtr (0) против IntPtr.Zero - PullRequest
24 голосов
/ 18 февраля 2009

Есть ли разница между двумя утверждениями:

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

Я видел много примеров, которые используют PInvoke, которые предпочитают первый синтаксис, если аргумент myPtr передается по ссылке в вызываемую функцию. Если я заменю все новые IntPtr (0) на IntPtr.Zero в моем приложении, это вызовет какой-либо ущерб?

Ответы [ 6 ]

24 голосов
/ 18 февраля 2009

IntPtr является типом значения, поэтому, в отличие от String.Empty, наличие статического свойства IntPtr.Zero

сравнительно мало.

Как только вы передадите IntPtr.Zero в любом месте, вы получите копию, поэтому для инициализации переменной это не имеет значения:

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

Есть одно исключение, и это сравнение:

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

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

Как уже сказано в нескольких постерах.

7 голосов
/ 18 февраля 2009

Они функционально эквивалентны, поэтому проблем не должно быть.

IntPtr.Zero представляет состояние структуры по умолчанию (оно объявлено, но конструктор не используется), поэтому значение по умолчанию intptr (void*) будет null. Однако, поскольку (void*)null и (void*)0 эквивалентны, IntPtr.Zero == new IntPtr(0)

Редактировать: Несмотря на то, что они эквивалентны, я рекомендую использовать IntPtr.Zero для сравнений, поскольку их проще читать.

5 голосов
/ 18 февраля 2009

Использование IntPtr.Zero позволит вам избежать нового экземпляра IntPtr.

из msdn :

Используйте это поле для эффективного определить, является ли экземпляр IntPtr было установлено в значение другое чем ноль

1 голос
/ 18 февраля 2009

Что произойдет, если вы передадите IntPtr.Zero по ссылке, и получатель попытается изменить ссылку? С этого момента IntPtr.Zero != new IntPtr(0) или получатель получит какое-то исключение при попытке внести изменение?

Я не уверен в этом, но это кажется разумным объяснением.

0 голосов
/ 05 марта 2013

JITter может встроить IntPtr.Zero так же, как встроенный IntPtr.Size.

0 голосов
/ 18 февраля 2009

Это в основном вопрос инкапсуляции (и производительности, но в гораздо меньшей степени). В какой-то момент в будущем Microsoft может решить (хотя это очень маловероятно), что значение указателя, унифицированного указателем, теперь будет равно 0xDEADBEEF, что делает весь код new IntPtr(0) недействительным.

Что касается производительности, MSDN говорит:

Например, предположим, что переменная ip является экземпляром IntPtr. Вы можете определить, было ли оно установлено, сравнивая его со значением, возвращаемым конструктором, например: «if ip! = New IntPtr (0) ...». Тем не менее, вызов конструктора для получения неустановленного указателя неэффективен. Лучше кодировать либо «if ip != IntPtr.Zero...», либо «if !IntPtr.Zero.Equals(ip)...».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...