C# DWORD и QWORD - безумие со знаком и без знака

Я заметил что DWord а также QWord Значения при записи в Реестр должны быть Подписанными Целыми числами, а не Беззнаковыми. Этот код вызовет исключение, если значение UInt64 или UInt32:

registryKey.SetValue(name, value);

По данным MSDN DWORD 32-разрядное целое число без знака (от 0 до 4294967295 в десятичном виде) https://msdn.microsoft.com/en-us/library/cc230318.aspx

Итак, чтобы написать новый DWORD значение в реестр, мне нужно привести его к целому числу со знаком, например:

UInt32 unsignedValue = (UInt32)someValue;
Int32 signedValue = (Int32)unsignedValue;
registryKey.SetValue(name, signedValue);

Передача значения без знака в метод SetValue вызовет исключение. Я что-то упустил или я просто отсталый?

2 ответа

Решение

По историческим причинам.NET API/ библиотеки обычно "подписаны", а не "подписаны + неподписаны".

Но в конце концов, signed int и unsigned int оба занимают одно и то же место в памяти, и для отрицательных значений не выполняется специальная обработка. Таким образом, вы можете сделать, как вы сказали: приведите значение без знака к знаку, запишите его с SetValue а затем, если вы посмотрите на значение в Regedit вы увидите, что это было написано "без знака".

Обратите внимание, что если ваша программа скомпилирована в "проверенном" режиме, более правильный код будет:

uint unsignedValue = ... // Your original value

int signedValue = unchecked((int)unsignedValue);
registryKey.SetValue(name, signedValue);

Потому что в "проверенном" режиме кастинг между int а также uint может выдать исключение, если преобразование невозможно.

Обратите внимание, что, как написано здесь:

Эта перегрузка SetValue хранит 64-битные целые числа в виде строк (RegistryValueKind.String). Чтобы сохранить 64-разрядные числа в качестве значений RegistryValueKind.QWord, используйте перегрузку SetValue(String, Object, RegistryValueKind), которая указывает RegistryValueKind.

Понятно, что вам придется делать ту же обработку для подписанного без знака.

На примере страницы RegistryKey.SetValue:

// Numeric values that cannot be interpreted as DWord (int) values
// are stored as strings.

Кажется, что сохраненные значения являются подписанными целочисленными значениями или строками.

Другие вопросы по тегам