【问题标题】:Is IntPtr.Zero equivalent to null?IntPtr.Zero 是否等同于 null?
【发布时间】:2010-11-30 05:19:59
【问题描述】:

我正在尝试将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
  );

我这样称呼它(目的是让第四个参数为空):

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

这和用 null 调用它是一样的吗?如果没有,我应该在声明或函数调用本身中更改什么?

我也很好奇是否应该使用SafeHandleHandleRef 而不是IntPtr 作为hFile 参考?我知道要确保在完成后使用CloseHandle(IntPtr) 关闭手柄,只是不确定是否有任何其他理由使用其他两个选项而不是IntPtr。我也在尽量避免使用不安全的代码。

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

【问题讨论】:

    标签: c# file-io asynchronous


    【解决方案1】:

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

    if (IntPtr.Zero == null)
    {
        // Won't enter here
    }
    

    会正确编译,但永远不会进入if

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

    <Features>strict</Features>
    

    【讨论】:

    • 抱歉后面的帖子,但这不是错误,因为 IntPtr.Zero 不等于 null - 因此 if 语句不起作用。
    • @Kobunite 然后尝试写if (IntPtr.Zero == "Hello") 看看会发生什么。会有编译时错误...问题是没有警告说比较不可能,也没有错误。代码被编译器简单地删除。查看生成的IL代码goo.gl/6zpPxN
    • 抱歉 necro,但它可以编译,因为它有效地使用 == 运算符重载来隐式转换为 (IntPtr?)IntPtr.Zero == (IntPtr?)null
    • @Marc 问题不在于缺少的错误...goo.gl/7o2fKM 问题是如果您尝试执行5 == null,您会收到警告,但如果您执行IntPtr.Zero == null你不会收到警告。有趣的是,编译器知道相等是不可能的,实际上它会删除代码。
    • 不知道为什么会这样编译,IntPtr是一个结构体,不应该和null比较,甚至不应该编译。
    【解决方案2】:

    对于您列出的 P/Invoke 目的,您应该使用 IntPtr.Zero 代替 NULL。但是请注意,这并不等同于 C# null 关键字。

    【讨论】:

      【解决方案3】:

      您不能将 null 分配给值类型。引用类型可以为空,例如,不引用对象实例,但值类型总是有值。

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

      【讨论】:

      • 显然 IntPtr 是 Chuck Norris。它可以与 null 进行比较,但在这种比较中永远不会为真。
      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 2017-01-20
      • 2016-02-12
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多