这两种说法有什么区别:
IntPtr myPtr = new IntPtr(0);
IntPtr myPtr2 = IntPtr.Zero;
如果 myPtr 参数由 ref 发送到被调用函数,我已经看到许多使用 PInvoke 的示例更喜欢第一种语法。如果我在我的应用程序中用 IntPtr.Zero 替换所有新的 IntPtr(0),它会造成任何损害吗?
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
}
正如几张海报已经说过的那样。
它们在功能上是等效的,所以应该不会引起任何问题。
IntPtr.Zero
表示结构的默认状态(已声明但未使用构造函数),因此 的默认intptr (void*)
值为null
. 然而,因为(void*)null
和(void*)0
是等价的,IntPtr.Zero == new IntPtr(0)
编辑:虽然它们是等价的,但我建议使用IntPtr.Zero
比较,因为它更容易阅读。
如果你通过IntPtr.Zero
ref 传递,而接收者试图修改引用会发生什么?从那一刻起,IntPtr.Zero != new IntPtr(0)
接收者是否会在尝试进行更改时收到某种异常?
我不确定这一点,但这似乎是一个合理的解释。
JITter 可以像内联 IntPtr.Size 一样内联 IntPtr.Zero。
这主要是一个问题封装(和性能,但程度要小得多)。在未来的某个时刻,微软可能会决定(尽管这不太可能)一个未初始化的指针值从现在开始等于0xDEADBEEF
,从而使所有new IntPtr(0)
代码无效。
就性能而言,MSDN 是这样说的:
例如,假设变量 ,
ip
是 的一个实例IntPtr
。您可以通过将其与构造函数返回的值进行比较来确定它是否已设置,例如:“ if ip != new IntPtr(0)...”。但是,调用构造函数来获取未初始化的指针是低效的。最好编码“if ip != IntPtr.Zero...
”或“if !IntPtr.Zero.Equals(ip)...
”。