C#中的隐式类型转换

tin*_*tes 33 c#

我有一个关于隐式类型转换的问题

为什么这种隐式类型转换在C#中有效?我已经知道隐式代码通常不起作用.

我这里有一个关于隐式类型转换的代码示例

 char c = 'a';
 int x = c;
 int n = 5;
 int answer = n * c;
 Console.WriteLine(answer);
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 76

更新:我今天使用这个问题作为我博客的主题.谢谢你提出的好问题.请参阅博客以了解将来的新增内容,更新,评论等.

http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx


我并不完全清楚你究竟在问什么."为什么"这些问题很难回答.但是我会对它进行拍摄.

首先,它有一个隐式转换,从字符代码为int(注意:这不是一个"隐式转换",这是一个"隐式转换")是合法的,因为C#规范明确指出,有从焦炭中的隐式转换为int在这方面,编译器是规范的正确实现.

现在,你可能明智地指出这个问题已被彻底乞求.为什么有从char到int的隐式转换?为什么语言的设计者认为这是添加到语言中的合理规则?

嗯,首先,明显的事情会阻止这种语言成为一种规则,这种情况并不适用.炭被实现为一个无符号的16位整数,它表示在一个UTF-16编码的字符,所以它可以被转换为一个USHORT而不损失精度,或者,对于这个问题,没有表示的变化.运行时只是将此位模式视为char,将处理相同的位模式作为ushort.

因此可以允许从char到ushort的转换.现在,仅仅因为有可能并不意味着这是一个好主意.显然,该语言的设计者认为隐式地将char转换为ushort是一个好主意,但隐含地将ushort转换为char则不是.(因为char to ushort是一个好主意,看起来合理的是char-to-anything-ushort-goes-to也是合理的,因此,char to int.另外,我希望很清楚为什么允许显式转换ushort to char是明智的;你的问题是隐含的转换.)

所以我们实际上有两个相关的问题:首先,为什么允许从ushort/short/byte/sbyte到char的隐式转换是个坏主意?第二,为什么允许从char到ushort的隐式转换是个好主意?

与您不同,我拥有语言设计团队的原始笔记.通过这些挖掘,我们发现了一些有趣的事实.

第一个问题在1999年4月14日的注释中有所涉及,其中出现了从字节转换为字符是否合法的问题.在C#的原始预发布版本中,这在短时间内是合法的.我已经对这些笔记进行了轻微的编辑,以便在不理解1999年代预发布的Microsoft代码名称的情况下使其清晰.我还强调了重点:

[语言设计委员会]选择提供从字节到字符的隐式转换,因为一个域完全包含在另一个域中.但是,现在,[运行时库]只提供带有字符和整数的Write方法,这意味着字节打印为字符,因为这最终是最好的方法.我们可以通过在Writer类上提供更多方法或通过删除隐式转换来解决这个问题.

有一个论据是为什么后者是正确的事情.毕竟,字节确实不是字符.诚然,可能会有一个 有用的映射从字节字符,但最终,23不表示相同的事情与ASCII值23的字符,在图23B表示相同的事情23L相同的方式.要求[图书馆作者]提供这种额外的方法只是因为我们的类型系统中的怪癖如何运作似乎相当薄弱.所以我建议我们将字节转换为char显式.

这些注释最后得出的结论是,byte-to-char应该是一个显式转换,而char-length-literal-in-range-char也应该是一个显式转换.

请注意,语言设计说明没有说明为什么ushort-to-char同时也被视为非法,但您可以看到相同的逻辑适用.当调用一个重载为M(int)和M(char)的方法时,当你传递一个ushort时,你想要将ushort视为一个数字而不是一个字符的几率是好的.ushort不是一个字符表示,就像ushort是一个数字表示一样,所以将转换非法也是合理的.

1999年9月17日决定让char进入ushort; 那天关于这个主题的设计说明简单地说"char to ushort也是一种合法的隐式转换",就是这样.在笔记中没有进一步阐述当天语言设计师头脑中发生的事情.

但是,我们可以做出有根据的猜测,为什么隐含的char-to-ushort被认为是个好主意.这里的关键思想是从数字到字符的转换是"可能是狡猾的"转换.它正在采取你不知道的东西是一个角色,并选择将其视为一个角色.这似乎是你想要明确表达的事情,而不是意外地允许它.但反之则不那么狡猾.C编程中有一个悠久的传统,即将字符视为整数 - 获取它们的基础值,或者对它们进行数学处理.

简而言之:使用数字作为角色可能是一个意外和一个错误似乎是合理的,但使用一个字符作为数字是有意和可取的似乎也是合理的.因此,这种不对称性反映在语言规则中.

这是否回答你的问题?

  • 下面是一个示例,说明了为什么这种隐式转换对我来说似乎是一个错误,这就是我最终到达此页面的原因。我有三个方法:`WriteString(string value)`、`WriteString(string value, int length)`和`WriteString(string value, int length, char padChar)` - 第一个用于写入不同长度的字符串,另外两个是定长的。“WriteString(foo, ' ')” 形式的错误调用(调用者省略了长度)编译时没有任何问题,因为编译器在没有警告的情况下解决了第二个“WriteString”重载。 (3认同)

gim*_*mpf 12

基本思想是导致潜在数据丢失的转换可能是隐含的,而可能导致数据丢失的转换必须是显式的(例如,使用强制转换操作符).

所以隐式转换charint将在C#中工作.

[编辑]正如其他人所指出的,a char是C#中的16位数字,因此这种转换只是从16位整数到32位整数,这是可能的,没有数据丢失.[/ edit]

C#支持隐式转换,"通常不起作用"的部分可能来自其他语言,可能是C++,其中一些光荣的string实现提供了对各种指针类型的隐式转换,在应用程序中创建了一些巨大的错误.

当您使用任何语言提供类型转换时,默认情况下也应默认为显式转换,并且仅针对特殊情况提供隐式转换.

  • 那么是什么解释了为什么在C#中没有从short back到char的隐式转换?这可以无损地完成; 你的逻辑表明应该存在从short到char的隐式转换,但是没有.为什么不? (4认同)

Dzm*_*uba 9

来自C#规范

6.1.2隐式数字转换隐式数字转换是:

•从sbyte到short,int,long,float,double或decimal.

•从byte到short,ushort,int,uint,long,ulong,float,double或decimal.

•从short到int,long,float,double或decimal.

•从ushort到int,uint,long,ulong,float,double或decimal.

•从int到long,float,double或decimal.

•从uint到long,ulong,float,double或decimal.

•从long到float,double或decimal.

•从ulong到float,double或decimal.

•从char到ushort,int,uint,long,ulong,float,double或decimal.

•从浮动到双重.

从int,uint,long或ulong到float以及从long或ulong到double的转换可能会导致精度损失,但绝不会导致数量级的损失.其他隐式数字转换永远不会丢失任何信息.char类型没有隐式转换,因此其他整数类型的值不会自动转换为char类型.


Gim*_*mly 5

从关于 char ( char (C# Reference)的 MSDN 页面:

char 可以隐式转换为 ushort、int、uint、long、ulong、float、double 或 decimal。但是,没有从其他类型到 char 类型的隐式转换。

这是因为他们已经实现了从 char 到所有这些类型的隐式方法。现在,如果你问他们为什么要实现它们,我真的不确定,当然可以帮助处理字符的 ASCII 表示或类似的东西。


ani*_*key 2

强制转换会导致数据丢失。这里char是16位,int是32位。因此,转换将在不丢失数据的情况下进行。

现实生活中的例子:如果没有外部帮助,我们可以将一个小容器放入一个大容器中,但反之亦然。