IntPtr.Zero相当于null吗?

SwD*_*n81 58 c# file-io asynchronous

我试图设置ReadFile为异步运行,根据MSDN,我需要设置lpNumberOfBytesReadnull:

"如果这是一个异步操作,请为此参数使用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
  );
Run Code Online (Sandbox Code Playgroud)

我这样称呼它(意图使第4个参数为null):

Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped);
Run Code Online (Sandbox Code Playgroud)

是否与使用null调用它相同?如果没有,我应该在声明或函数调用本身中更改什么?

我也好奇,如果我应该使用SafeHandleHandleRef代替IntPtrhFile参考?我知道CloseHandle(IntPtr)当我完成它时确保关闭手柄,只是不确定是否有任何其他理由使用其他两个选项IntPtr.我也在努力避免使用不安全的代码.

编辑:事实证明,我不应该设置第四个参数IntPtr.Zero,因为即使我异步运行,它仍然可以立即返回.见异步磁盘I/O.啊,我喜欢自相矛盾的故事.

Mic*_*ael 71

对于你已经列出的P/Invoke目的,你应该用IntPtr.Zero它代替NULL.但请注意,这不等同于C#null关键字.


Yan*_*ton 8

您不能将null分配给值类型.reference-type可以为null,如未引用对象实例,但value-type始终具有值.

IntPtr.Zero只是一个表示空指针的常量值.

  • 显然 IntPtr 是 Chuck Norris。它可以与 null 进行比较,但在这种比较中永远不会为真。 (2认同)

xan*_*tos 7

请注意,C#> = 2.0中存在一个错误(功能??),其中

if (IntPtr.Zero == null)
{
    // Won't enter here
}
Run Code Online (Sandbox Code Playgroud)

将正确编译,但它不会进入if.

我在roslyngithub上打开了一个问题,他们回答说他们不会修复它,因为有些项目是使用警告 - 错误构建的.仍然有一个部分修复:有一个strict生成此警告的编译模式:

<Features>strict</Features>
Run Code Online (Sandbox Code Playgroud)

  • 对于后面的帖子很抱歉,但这不是一个错误,因为IntPtr.Zero不等于null - 所以if语句不起作用. (15认同)
  • @Marc问题不在于遗漏的错误... http://goo.gl/7o2fKM问题是,如果你尝试做`5 == null`你会得到一个警告,但如果你做`IntPtr .Zero == null`你不会收到警告.有趣的是,编译器知道相等是不可能的,事实上它将删除代码. (3认同)