为什么在C#中使用无符号CLR类型如此困难?
在我开始使用C之前,我主要是C/C++背景。我在C#的第一个项目中所做的一件事就是制作一个这样的类为什么在C#中使用无符号CLR类型如此困难?,c#,.net,casting,language-design,unsigned,C#,.net,Casting,Language Design,Unsigned,在我开始使用C之前,我主要是C/C++背景。我在C#的第一个项目中所做的一件事就是制作一个这样的类 class Element{ public uint Size; public ulong BigThing; } 我当时感到羞愧的是,这需要演员: int x=MyElement.Size; 同样 int x=5; uint total=MyElement.Size+x; 为什么语言设计者决定使有符号和无符号整数类型不可隐式强制转换?为什么在整个.Net库中没有更多地使用无符号类型
class Element{
public uint Size;
public ulong BigThing;
}
我当时感到羞愧的是,这需要演员:
int x=MyElement.Size;
同样
int x=5;
uint total=MyElement.Size+x;
为什么语言设计者决定使有符号和无符号整数类型不可隐式强制转换?为什么在整个.Net库中没有更多地使用无符号类型?例如,String.Length
永远不能为负,但它是一个有符号整数
为什么语言设计者决定不使用有符号和无符号整数类型
隐式铸造
因为这可能会丢失数据或引发任何异常,通常隐式允许这两种情况都不是一件好事。(诚然,从long到double的隐式转换也可能丢失数据,但方式不同。)
为什么在整个.Net库中没有更多地使用无符号类型
未签名类型不符合CLS-并非所有.NET语言都始终支持它们。例如,Visual Basic在.NET 1.0和1.1中对无符号数据类型没有“本机”支持;它被添加到2.0语言中。(你仍然可以使用它们,但它们不是语言本身的一部分——例如,你不能使用普通的算术运算符。)因为隐式地将3B的无符号整数转换为有符号整数将会爆炸
Unsigned的最大值是signed的两倍。这与你不能将长数转换为整数的原因是一样的。还有Jon的答案,仅仅因为一个无符号的数字不能是负数并不意味着它不大于一个有符号的数字
uint
是0到4294967295,但是int
是-2147483648到2147483647。在int
的最大损失上有足够的空间。第二点:因为他们希望CLR与没有未签名数据类型的语言兼容(读:VB.NET)
我当时感到羞愧的是,这需要演员:
int x=MyElement.Size;
但你在这里自相矛盾。如果您真的(真的)需要大小是无符号的,那么将其分配给(有符号的)x是一个错误。代码中的一个严重缺陷
例如,String.Length永远不能为负,但它是一个有符号整数
但是String.IndexOf可以返回一个负数,如果String.Length和Index的值是不同类型的,那就很麻烦了
虽然从理论上讲,无符号字符串.Length(4GB上限)有其优点,但在实践中,即使是当前的2GB也足够大(因为这种长度的字符串很少见,而且无论如何都不可行)
这样的答案是:为什么首先使用unSt签名?< /P>即使在C++中,从unStokes到签名或返回的一个强制语句会引起警告。我意识到我的第一个案例很弱,但我的第二个案例更像我的意思,因为那里没有数据丢失的机会,除非
x
在第二次计数中是否定的,请参见我下面的回答…你删除了另一个问题吗?反正返回错误;这就是解决方案:)我检查它。@Aristo是的,它是如此明显,我认为它并不重要,所以我删除了它。。我不到10k,所以现在我甚至看不到我被删除的问题来取消删除。“虽然我可能错了”-你是说.NET可能错了?@PostMan:我刚刚找到了更多的信息。。。will edit.VB.net自至少2.0起就有未签名的数字。我之前没有意识到它们丢失了,但这很有意义——它们在VB中没有及时进入CLS。但是在.NET v2中更改字符串类(或者,在这个问题上,永远更改)会破坏大量代码。有足够声誉的人可以修改它,说“3B的无符号整数变成有符号整数吗?”他的意图很清楚,只是一个输入错误。嗯,因为它允许更广泛地表达无符号数字吗?@Henk:我认为使用int
比较尴尬的一个例子是Array.Length
。人们永远不会期望数组的大小为负数,而使用有符号类型会将(报告的)数组大小限制在2GB以下。此外,数组索引可能永远不会为负。现在,有了LongLength
属性,它将数组大小报告为Int64
——但它仍然将其报告为有符号值。在这些情况下,最重要的考虑因素是.NET的设计者选择使未签名类型不符合CLS。在这一点上不太可能改变的东西。@Paul:decimal
的范围更广。这个问题是关于unsigned的实际用途。OP没有提供任何信息。@LBushkin:我肯定我会发现一个未签名的长度要尴尬得多。想象一下扩展到循环索引和各种计数器。最终,到处都会出现未签名和转换。我在C和C++中看到了,不想回去(-:亨克:原则上我同意你的观点,只使用在库中签名的或未签名的值确实有助于避免不必要的(和令人沮丧的)转换。然而,在不了解根本原因的情况下(CLS遵从)可能这个决定是错误的和武断的。这就是我使用形容词“笨拙”时的意思。顺便说一句,还应该注意的是,并不是C#中涉及有符号和无符号类型的所有表达式都需要转换-例如,比较通常是好的:int x=10;uint y=20;if(x
。