С#: назначить 0xFFFFFFFF для int

Я хочу использовать номер HEX для присвоения значения int:

int i = 0xFFFFFFFF; // effectively, set i to -1

Понятно, компилятор жалуется. Вопрос: как я могу сделать выше работу?

Вот почему мне это нужно. WritableBitmap класс предоставляет массив пикселей как int []. Поэтому, если я хочу установить пиксель в синий цвет, я бы сказал: 0xFF0000FF (ARGB) (-16776961)

Плюс мне любопытно, есть ли изящное решение времени компиляции.

Я знаю, что есть:

int i = BitConverter.ToInt32(new byte[] { 0xFF, 0x00, 0x00, 0xFF }, 0);

но он не является ни элегантным, ни компиляционным.

Ответы

Ответ 1

Вам просто нужно unchecked cast:

unchecked
{
    int i =  (int)0xFFFFFFFF;

    Console.WriteLine("here it is: {0}", i);
}

Ответ 2

Дайте кому-нибудь рыбу, и вы кормите их в течение дня. Научите их обращать внимание на сообщения об ошибках компилятора, и им не нужно задавать вопросы в Интернете, на которые отвечает сообщение об ошибке.

int i = 0xFFFFFFFF; 

дает:

Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists 
(are you missing a cast?)

Обратите внимание на сообщение об ошибке и попробуйте добавить листинг:

int i = (int)0xFFFFFFFF; 

Теперь ошибка:

Constant value '4294967295' cannot be converted to a 'int' 
(use 'unchecked' syntax to override)

Снова обратите внимание на сообщение об ошибке. Использовать непроверенный синтаксис.

int i = unchecked((int)0xFFFFFFFF); 

или

unchecked
{
    int i = (int)0xFFFFFFFF; 
}

И теперь нет ошибок.

В качестве альтернативы использованию непроверенного синтаксиса вы можете указать /checked- в переключателях компилятора, если хотите жить опасно.

Бонусный вопрос:

Что делает буквальный a uint в первую очередь?

Тип целочисленного литерала не зависит от того, является ли он шестнадцатеричным или десятичным. Скорее всего:

  • Если десятичный литерал имеет суффиксы U или L, то это будет uint, long или ulong, в зависимости от того, какую комбинацию суффиксов вы выберете.
  • Если у него нет суффикса, мы берем значение литерала и видим, вписывается ли он в диапазон int, uint, long или ulong. Какой бы ни был первый в этом списке, это тип выражения.

В этом случае шестнадцатеричный литерал имеет значение, которое находится за пределами диапазона int, но внутри диапазона uint, поэтому оно рассматривается как uint.

Ответ 3

Неконтролируемый синтаксис кажется немного gar 'ish (!) по сравнению с различными однобуквенными числовыми суффиксами.

Итак, я попробовал shellfish:

static public class IntExtMethods
{
    public static int ui(this uint a)
    {
        return unchecked((int)a);
    }
}

Тогда

int i = 0xFFFFFFFF.ui();

Потому что в озере больше рыбы.

Примечание: это не постоянное выражение, поэтому оно не может использоваться для инициализации поля перечисления, например.