Новый IntPtr (0) против IntPtr.Zero
Есть ли разница между двумя утверждениями:
IntPtr myPtr = new IntPtr(0);
IntPtr myPtr2 = IntPtr.Zero;
Я видел много образцов, которые используют PInvoke, которые предпочитают первый синтаксис, если аргумент myPtr отправляется ref по вызываемой функции.
Если я заменил все новое IntPtr (0) на IntPtr.Zero в моем приложении, это приведет к повреждению?
Ответы
Ответ 1
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 now a copy
Есть одно исключение, и это сравнение:
if( myPtr != new IntPtr(0) ) {
//new pointer initialised to check
}
if( myPtr != IntPtr.Zero ) {
//no new pointer needed
}
Как уже было сказано несколько плакатов.
Ответ 2
Они функционально эквивалентны, поэтому это не должно вызывать никаких проблем.
IntPtr.Zero представляет состояние структуры по умолчанию (оно объявлено, но конструктор не используется), поэтому значение по умолчанию для intptr (void *) будет равно null. Однако, поскольку (void *) null и (void *) 0 эквивалентны, IntPtr.Zero == new IntPtr (0)
Изменить: Пока они эквивалентны, я рекомендую использовать IntPtr.Zero для сравнения, так как это просто читать легче.
Ответ 3
Использование IntPtr.Zero
позволит вам избежать появления нового экземпляра IntPtr
.
из msdn:
Используйте это поле для эффективного использования определить, является ли экземпляр Для IntPtr установлено значение другое чем ноль
Ответ 4
Что произойдет, если вы передадите IntPtr.Zero
по ссылке ref, и получатель попытается изменить ссылку? С этого момента будет IntPtr.Zero != new IntPtr(0)
, или получатель получит какое-то исключение при попытке внести изменения?
Я не уверен в этом, но это кажется разумным объяснением.
Ответ 5
JITTER может встроить IntPtr.Zero таким же образом, как и IntPtr.Size.
Ответ 6
Это главным образом инкапсуляция вопроса (и производительности, но в гораздо меньшей степени). В какой-то момент в будущем Microsoft может решить (хотя это очень маловероятно), что униализированное значение указателя будет теперь равно равным 0xDEADBEEF
, что делает код new IntPtr(0)
недействительным.
Что касается производительности, MSDN говорит следующее:
Например, предположим, что переменная ip
является экземпляром IntPtr
. Вы можете определить, было ли оно установлено, сравнивая его со значением, возвращаемым конструктором, например: "if ip!= New IntPtr (0)...". Однако вызов конструктора для получения неинтеллизированного указателя неэффективен. Лучше закодировать либо "if ip != IntPtr.Zero...
", либо "if !IntPtr.Zero.Equals(ip)...
".