2009-08-24 6 views
10

Das sollte einfach sein: Ich sehe überall Leute IntPtr verwenden, gibt es einen Grund, warum ich stattdessen UIntPtr verwenden sollte?IntPtr vs UIntPtr

+0

Wow, ich wusste nicht einmal, dass es ein 'UIntPtr' gibt. Können wir es für die nutzloseste Eigenschaft von '.NET' nominieren? – ja72

Antwort

8

Es scheint nicht, als gäbe es einen guten Grund zu. Aus der Dokumentation:

Bemerkungen

...

Der IntPtr-Typ CLS-kompatibel, während des UIntPtr Typ nicht ist. Nur Der IntPtr-Typ wird in der allgemeinen Sprachlaufzeit verwendet. Der UIntPtr-Typ ist , der hauptsächlich bereitgestellt wird, um Architektursymmetrie mit dem Typ IntPtr beizubehalten.

+1

Diese Antwort wird als falsch markiert. – xamid

7

Nun according to MicrosoftUIntPtr wird hauptsächlich für architektonische Symmetrie zur Verfügung gestellt. Ein weiterer interessanter Punkt ist, dass UIntPtr nicht CLS-konform ist.

Auf der Oberfläche scheint IntPtr die bevorzugte Option zu sein. Wenn Sie jedoch wissen, dass Sie Zeigerarithmetik ausführen werden, dann könnte UIntPtr eine bessere Wahl sein, da es in der Off-Chance ein obskures Problem mit negativen Werten gab.

1

Es gibt einen großen Unterschied .. Zum Beispiel neue UIntPtr(0xC01E0001) ergibt einen Zeiger bei 3223191553, aber IntPtr(0xC01E0001) führt zu einer System.OverflowException: "Arithmetische Operation führte zu einem Überlauf". Das heißt, 0xC01E0001 ist größer als MaxValue für Int32.

Also, wenn man noch einen solchen Zeiger will, eine negative ganze Zahl muss für IntPtr als interne Wert verwendet werden soll, wie

unchecked((IntPtr)(int)0xC01E0001) 

Um Ihre Frage zu beantworten: Für Werte größer als Int32.MaxValue es ist einfacher und irgendwie sauberer UIntPtr zu verwenden. Es ist wahrscheinlich immer die beste Lösung, da Zeiger immer als vorzeichenlos gelten.

+0

OverflowException kann nicht reproduziert werden nach 'var p1 = new IntPtr (0xC01E0001); var p2 = (IntPtr) 0xC01E0001; ' –