我有一个关于隐式类型转换的问题
为什么这种隐式类型转换在C#中有效?我了解到隐式代码通常是不起作用的。
我在这里有一个关于隐式类型转换的代码示例
char c = 'a';
int x = c;
int n = 5;
int answer = n * c;
Console.WriteLine(answer);
发布于 2009-10-01 11:45:06
强制转换会导致数据丢失。这里char是16位,int是32位。因此,转换将在不丢失数据的情况下发生。
现实生活中的例子:没有外部帮助,我们可以把小容器放入大容器,但反之亦然。
发布于 2009-10-01 16:19:17
更新:我今天将这个问题作为我博客的主题。谢谢你这个很棒的问题。请查看博客,了解未来的新增内容、更新、评论等。
http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx
我不完全清楚你到底在问什么。“为什么”的问题很难回答。但我会试一试。
首先,具有从char到int的隐式转换的代码(注意:这不是“隐式转换”,这是“隐式转换”)是合法的,因为C#规范明确指出存在从char到int的隐式转换,并且在这方面,编译器是规范的正确实现。
现在,您可能会明智地指出,这个问题已经被彻底地恳求了。为什么会有从char到int的隐式转换?为什么语言的设计者认为这是添加到语言中的一条明智的规则?
好吧,首先,阻止这成为语言规则的显而易见的事情并不适用。char被实现为表示UTF-16编码中的字符的无符号16位整数,因此它可以在不损失精度的情况下转换为ushort,或者,就这一点而言,不更改表示法。运行时只是简单地将此位模式视为char,而将相同的位模式视为ushort。
因此,可以允许从char到ushort的转换。现在,仅仅因为某些事情是可能的并不意味着它是一个好主意。显然,该语言的设计者认为将char隐式转换为ushort是一个好主意,但将ushort隐式转换为char并非如此。(既然char到ushort是个好主意,那么char - to -And ushort- to也是合理的,因此char到int也是合理的。另外,我希望大家明白为什么允许将ushort显式转换为char是合理的;您的问题是关于隐式转换的。)
所以我们实际上有两个相关的问题:首先,为什么允许从ushort/short/byte/sbyte到char的隐式转换是一个坏主意?其次,为什么允许从char到ushort的隐式转换是一个好主意?
与您不同的是,我有来自语言设计团队的原始笔记。通过这些挖掘,我们发现了一些有趣的事实。
1999年4月14日的笔记中介绍了第一个问题,其中出现了从字节转换为字符是否合法的问题。在C#的原始预发布版本中,这在很短的一段时间内是合法的。我稍微编辑了一下注释,以便在不理解1999年预发布的微软代码名称的情况下使它们清晰。我还强调了重要的几点:
语言设计委员会选择提供从字节到字符的隐式转换,因为其中一个的域完全包含在另一个中。然而,现在运行时库只提供了使用chars和int的Write方法,这意味着字节会以字符的形式打印出来,因为这是最好的方法。我们可以通过在Writer类上提供更多的方法或者删除隐式转换来解决这个问题。关于为什么后者是正确的事情,有一个争论。毕竟,字节实际上不是字符。是的,从字节到字符可能有一个有用的映射,但最终,23并不表示与具有ascii值23的字符相同的东西,就像23B表示23L一样。仅仅因为我们的类型系统中的一个怪癖是如何工作的,要求库作者提供这个额外的方法似乎是相当软弱的。所以我建议我们显式地从byte转换到char。
然后,注释的结论是字节到字符应该是显式转换,字符范围内的整型文字也应该是显式转换。
注意,语言设计说明没有指出为什么ushort-to-char同时也是非法的,但您可以看到同样的逻辑也适用。当调用一个重载为M(int)和M(char)的方法时,当您向它传递ushort时,您很可能希望将ushort视为一个数字,而不是一个字符。而且ushort不是字符表示,就像ushort是数字表示一样,因此将该转换设为非法似乎也是合理的。
让char转到ushort的决定是在1999年9月17日做出的;当天关于这个主题的设计笔记简单地说明了"char到ushort也是一种合法的隐式转换“,仅此而已。在笔记中,语言设计者的头脑中没有进一步的解释。
然而,我们可以有根据地猜测为什么隐式char- to -ushort被认为是一个好主意。这里的关键思想是从数字到字符的转换是一个“可能不可靠”的转换。它是把你不知道的东西变成一个角色,并选择把它当作一个角色。这看起来像是你想要明确地说出你正在做的事情,而不是意外地允许它。但反过来就没那么不靠谱了。在C编程中,将字符视为整数的传统由来已久--获取它们的基础值,或者对它们进行数学运算。
简而言之:使用数字作为字符可能是意外和错误,这似乎是合理的,但使用字符作为数字是故意和可取的,这似乎也是合理的。因此,这种不对称性反映在语言的规则中。
这回答了你的问题吗?
发布于 2009-10-01 11:41:03
基本思想是,导致潜在数据丢失的转换可以是隐式的,而可能导致数据丢失的转换必须是显式的(例如,使用cast操作符)。
因此,从char
到int
的隐式转换将在C#中工作。
正如其他人指出的那样,在C#中,编辑是一个16位的数字,所以这个转换只是从16位整数到32位整数,这是可能的,而不会丢失数据。/ char
C#支持隐式转换,“通常不工作”这一部分可能来自其他语言,可能是C++,其中一些优秀的string
实现提供了到各种指针类型的隐式转换,从而在应用程序中产生了一些巨大的错误。
当您在任何语言中提供类型转换时,默认情况下也应该使用显式转换,并且只在特殊情况下提供隐式转换。
https://stackoverflow.com/questions/1503430
复制相似问题