Это должно быть просто: я вижу везде, где люди используют IntPtr, есть ли причина, по которой мне следует использовать вместо UIntPtr?

12
devoured elysium 24 Авг 2009 в 06:57
Вау, я даже не знал, что это UIntPtr. Можем ли мы назвать его самой бесполезной функцией .NET?
 – 
John Alexiou
30 Авг 2014 в 23:50

3 ответа

Лучший ответ

Не похоже, чтобы для этого была веская причина. Из документов:

< Сильный > Заметки

...

Тип IntPtr совместим с CLS, а тип UIntPtr - нет. Только тип IntPtr используется в общем языковая среда . Тип UIntPtr - предоставлено в основном для обслуживания архитектурная симметрия с IntPtr тип.

9
womp 24 Авг 2009 в 07:03
3
Этот ответ отмечен как правильный, но является неправильным.
 – 
xamid
10 Июл 2015 в 02:47

Что ж, согласно Microsoft UIntPtr предназначен в основном для архитектурной симметрии. Еще один интересный момент: UIntPtr не соответствует требованиям CLS.

На первый взгляд может показаться, что предпочтительным вариантом является IntPtr. Однако, если вы знаете, что будете выполнять арифметические операции с указателями, то UIntPtr может быть лучшим выбором, так как, возможно, возникла какая-то неясная проблема, связанная с отрицательными значениями.

8
Brian Gideon 24 Авг 2009 в 07:16

Существует большая разница .. Например, в 32-битном приложении новый UIntPtr(0xC01E0001) приводит к указателю на 3223191553, но IntPtr(0xC01E0001) приводит к System.OverflowException: "Арифметическая операция привела к переполнению. ". Это потому, что 0xC01E0001 больше, чем MaxValue для Int32.

Поэтому, если кому-то по-прежнему нужен такой указатель, в качестве внутреннего значения для IntPtr необходимо использовать отрицательное целое число, например

unchecked((IntPtr)(int)0xC01E0001)

Чтобы ответить на ваш вопрос: для значений больше Int32.MaxValue проще и чище использовать UIntPtr. Вероятно, это всегда лучшее решение, поскольку указатели всегда считаются беззнаковыми.

2
xamid 15 Ноя 2018 в 04:45
Невозможно воспроизвести OverflowException с помощью var p1 = new IntPtr(0xC01E0001); var p2 = (IntPtr)0xC01E0001;
 – 
Chris Xue
11 Авг 2017 в 13:10
Вероятно, это потому, что вы используете 64-битную архитектуру, в то время как я использовал только 32-битную. Итак, по сути, я использовал Int32, вы использовали Int64. Чтобы произвести переполнение, вам нужны большие числа. Я отредактировал свой ответ.
 – 
xamid
15 Ноя 2018 в 04:45