新的IntPtr(0)与IntPtr.Zero

时间:2009-02-18 08:26:12

标签: c# .net pinvoke

这两个陈述之间是否有任何区别:

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

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

6 个答案:

答案 0 :(得分:24)

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
}

正如一些海报已经说过的那样。

答案 1 :(得分:7)

它们在功能上是等效的,所以它应该没有问题。

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

修改虽然它们是等效的,但我建议您使用IntPtr.Zero进行比较,因为它更容易阅读。

答案 2 :(得分:5)

使用IntPtr.Zero可以避免IntPtr的新实例。

来自msdn

  

有效地使用此字段   确定是否有实例   IntPtr已设置为其他值   比零

答案 3 :(得分:1)

如果您通过ref传递IntPtr.Zero并且收件人尝试修改引用会发生什么?从那一刻开始,会IntPtr.Zero != new IntPtr(0),还是收件人在尝试进行更改时会收到某种异常?

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

答案 4 :(得分:0)

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

答案 5 :(得分:-2)

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

就性能而言,MSDN说:

  

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