Por que Array.Length é um int e não um uint

Por que Array.Length é um int e não um uint . Isso me incomoda (apenas um pouco), porque um valor de comprimento nunca pode ser negativo.

Isso também me forçou a usar um int para uma propriedade length em minha própria class, porque quando você especifica um valor int, isso precisa ser convertido explicitamente …

Portanto, a questão final é: existe algum uso para um int não assinado ( uint )? Até a Microsoft parece não usá-los.

O Unsigned int não é compatível com CLS e, portanto, restringiria o uso da propriedade aos idiomas que implementam um UInt .

Veja aqui:

Framework 1.1

Introdução à biblioteca de classs do .NET Framework

Framework 2.0

Visão Geral da Biblioteca de Classes do .NET Framework

Muitas razões:

  • uint não é compatível com CLS, portanto, fazer um tipo de array (array) dependente dele teria sido problemático
  • O tempo de execução, conforme projetado originalmente, proíbe qualquer object no heap que ocupe mais de 2 GB de memory. Como a matriz de tamanho máximo que seria menor ou igual a esse limite seria new byte [int.MaxValue], seria confuso para as pessoas conseguir gerar comprimentos de array positivos, mas ilegais.
    • Observe que essa limitação foi um pouco removida na versão 4.5 , embora o comprimento padrão como int permaneça.
  • Historicamente, o C # herda muito de sua syntax e convenção de C e C ++. Nessas matrizes são simplesmente aritmética de pointers, então a indexação de matriz negativa era possível (embora normalmente ilegal e perigosa). Uma vez que muito código existente assume que o índice de matriz está assinado, isso teria sido um fator
  • Em uma nota relacionada, o uso de números inteiros assinados para índices de matriz em C / C ++ significa que a interoperabilidade com essas linguagens e funções não gerenciadas exigiria o uso de ints nessas circunstâncias, o que pode ser confundido devido à inconsistência.
  • A implementação do BinarySearch (um componente muito útil de muitos algoritmos) depende de ser capaz de usar o intervalo negativo do int para indicar que o valor não foi encontrado e o local em que tal valor deve ser inserido para manter a sorting.
  • Ao operar em uma matriz, é provável que você queira obter um deslocamento negativo de um índice existente. Se você usasse um deslocamento que o levaria além do início da matriz usando a unidade, o comportamento de agrupamento tornaria o seu índice possivelmente legal (em que é positivo). Com um int, o resultado seria ilegal (mas seguro, já que o tempo de execução protegeria contra a leitura de memory inválida)

Eu acho que isso também pode ter a ver com simplificar as coisas em um nível inferior, já que Array.Length será naturalmente adicionado a um número negativo em algum ponto, se Array.Length não estiver assinado, e adicionado a um int negativo (complemento de dois) , pode haver resultados confusos.

Parece que ninguém forneceu resposta para “a questão final”.

Acredito que o uso primário de ints não assinados é fornecer uma interface mais fácil com sistemas externos (P / Invoke e similares) e para cobrir as necessidades de várias linguagens sendo portadas para o .NET.

Geralmente, valores inteiros são assinados, a menos que você precise explicitamente de um valor não assinado. É apenas o jeito que eles são usados. Eu posso não concordar com essa escolha, mas é assim que é.

Por enquanto, com as restrições típicas de memory de hoje, se sua matriz ou estrutura de dados similar precisar de um tamanho UInt32, você deve considerar outras estruturas de dados.

Com uma matriz de bytes, Int32 lhe dará 2 GB de valores