Почему беззнаковые типы CLR так сложно использовать в C #? - PullRequest
9 голосов
/ 16 июля 2010

Я пришел в основном из C / C ++, прежде чем начал использовать C #.Одна из вещей, которые я сделал с моим первым проектом на C #, заключалась в создании такого класса

class Element{
  public uint Size;
  public ulong BigThing;
}

. Затем меня обескуражил тот факт, что для этого требуется приведение:

int x=5;
uint total=MyElement.Size+x;

Почему разработчики языка решили сделать целочисленные типы со знаком и без знака неявно кастируемыми?И почему неподписанные типы не используются больше в библиотеке .Net?Например, String.Length никогда не может быть отрицательным, но это целое число со знаком.

Ответы [ 5 ]

18 голосов
/ 16 июля 2010

Почему разработчики языка решили сделать целочисленные типы со знаком и без знака неявно кастируемыми?

Поскольку это может привести к потере данных или возникновению какого-либо исключения, ни одно из которых, как правило, не следует разрешать неявно.(Неявное преобразование из long в double тоже может привести к потере данных, но по-другому.)

И почему неподписанные типы не используются более широко в библиотеке .Net

Типы без знака не совместимы с CLS - не все языки .NET всегда поддерживали их.Например, в Visual Basic не было «встроенной» поддержки неподписанных типов данных в .NET 1.0 и 1.1;он был добавлен в язык для 2.0.(Вы все еще могли бы использовать их, но они не были частью самого языка - вы не могли, например, использовать обычные арифметические операторы.)

4 голосов
/ 16 июля 2010

Наряду с ответом Джона, только то, что число без знака не может быть отрицательным, не означает, что оно не больше, чем число со знаком. uint - от 0 до 4 294 967 295, но int - от 2 147 483 648 до 2 147 483 647. Много места выше int макс для потерь.

1 голос
/ 16 июля 2010

Я был тогда огорчен тем фактом, что это требует каста:

 int x=MyElement.Size;

Но вы противоречите себе здесь. Если вам действительно (действительно) нужно, чтобы Size был без знака, тогда присвоение его (подписанному) x является ошибкой. Глубокий недостаток в вашем коде.

Например, String.Length никогда не может быть отрицательным, но это целое число со знаком

Но String.IndexOf может возвращать отрицательное число, и было бы неудобно, если бы значения String.Length и Index были разных типов.

И хотя теоретически было бы целесообразно использовать String.Length без знака (ограничение 4 ГБ), на практике даже нынешние 2 ГБ достаточно велики (поскольку строки такой длины редки и в любом случае не работают).

Итак, настоящий ответ таков: зачем вообще использовать unsigned?

1 голос
/ 16 июля 2010

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

Unsigned имеет двойное максимальное значение подписанного. Это та же самая причина, по которой вы не можете разыграть long для int.

0 голосов
/ 16 июля 2010

По второму счету: потому что они хотели, чтобы CLR был совместим с языками, у которых нет типов данных без знака (читай: VB.NET).

...