Является ли IntPtr.Zero эквивалентным нулю?

Я пытаюсь настроить ReadFile для запуска асинхронно и согласно MSDN, мне нужно установить lpNumberOfBytesRead в null:

"Используйте NULL для этого параметра, если это асинхронная операция, чтобы избежать потенциально ошибочных результатов."

Например, если у меня есть следующее:

  [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  public static extern bool ReadFile(
     IntPtr hFile,
     out byte[] aBuffer,
     int cbToRead,
     IntPtr cbThatWereRead,
     ref OVERLAPPED pOverlapped
  );

и я называю это так (с намерением иметь 4-й параметр, равный нулю):

Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped);

будет ли это то же самое, что вызвать его с нулевым значением? Если нет, что я должен изменить в объявлении или в самом вызове функции?

Мне также было любопытно, следует ли использовать SafeHandle или HandleRef вместо IntPtr для ссылки hFile? Я знаю, чтобы убедиться, что я закрываю дескриптор с помощью CloseHandle(IntPtr), когда я закончил с этим, просто не уверен, есть ли причина использовать другие две опции над IntPtr. Я также стараюсь избегать использования небезопасного кода.

EDIT: Как оказалось, я не должен был устанавливать четвертый параметр в IntPtr.Zero в любом случае, потому что, хотя я работаю асинхронно, он все равно может вернуться сразу. См. Асинхронный дисковый ввод-вывод. Ах, я люблю противоречивые истории.

Ответ 1

Для целей P/Invoke, как вы указали, вы должны использовать IntPtr.Zero вместо NULL. Обратите внимание, что это не эквивалентно ключевому слову С# NULL.

Ответ 2

Вы не можете назначить значение null для значения. Тип ссылки может быть нулевым, как и в, не ссылаться на экземпляр объекта, но тип значения всегда имеет значение.

IntPtr.Zero - это просто постоянное значение, которое представляет нулевой указатель.