26

这两种说法有什么区别:

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

如果 myPtr 参数由 ref 发送到被调用函数,我已经看到许多使用 PInvoke 的示例更喜欢第一种语法。如果我在我的应用程序中用 IntPtr.Zero 替换所有新的 IntPtr(0),它会造成任何损害吗?

4

6 回答 6

26

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
}

正如几张海报已经说过的那样。

于 2009-02-18T08:50:21.467 回答
7

它们在功能上是等效的,所以应该不会引起任何问题。

IntPtr.Zero表示结构的默认状态(已声明但未使用构造函数),因此 的默认intptr (void*)值为null. 然而,因为(void*)null(void*)0是等价的,IntPtr.Zero == new IntPtr(0)

编辑:虽然它们是等价的,但我建议使用IntPtr.Zero比较,因为它更容易阅读。

于 2009-02-18T08:28:29.333 回答
5

的使用IntPtr.Zero将允许您避免IntPtr.

来自msdn

使用此字段可以有效地确定 IntPtr 的实例是否已设置为非零值

于 2009-02-18T08:32:16.580 回答
1

如果你通过IntPtr.Zeroref 传递,而接收者试图修改引用会发生什么?从那一刻起,IntPtr.Zero != new IntPtr(0)接收者是否会在尝试进行更改时收到某种异常?

我不确定这一点,但这似乎是一个合理的解释。

于 2009-02-18T08:40:34.657 回答
0

JITter 可以像内联 IntPtr.Size 一样内联 IntPtr.Zero。

于 2013-03-04T22:48:13.353 回答
-2

这主要是一个问题封装(和性能,但程度要小得多)。在未来的某个时刻,微软可能会决定(尽管这不太可能)一个未初始化的指针值从现在开始等于0xDEADBEEF,从而使所有new IntPtr(0)代码无效。

就性能而言,MSDN 是这样说的:

例如,假设变量 ,ip是 的一个实例IntPtr。您可以通过将其与构造函数返回的值进行比较来确定它是否已设置,例如:“ if ip != new IntPtr(0)...”。但是,调用构造函数来获取未初始化的指针是低效的。最好编码“ if ip != IntPtr.Zero...”或“ if !IntPtr.Zero.Equals(ip)...”。

于 2009-02-18T08:30:50.670 回答