【问题标题】:What's the benefit of implicit converting a char to an integer?将 char 隐式转换为整数有什么好处?
【发布时间】:2013-01-26 10:52:25
【问题描述】:

只是出于好奇...

我发现使用 Char 类型会产生令人讨厌的副作用,所以我想知道为什么设计师选择了类似的行为。 由于隐式转换,以下是有效的:

int x = 'A';

但是,以下内容让我有点困惑,因为容易导致误解:

int y = 'P' + 'Q';

既然一个字符串是由字符组成的,而字符串的“总和”产生另一个字符串,为什么字符的“总和”应该给出不同的东西?

另一个更糟的:

string s1 = 'H' + "ello"; //yields "Hello"
string s2 = 'H' + 'e' + "llo";  //yields "173llo"

所有这一切都是因为隐式转换。 我想知道这样做有什么好处,而不是强迫用户明确地将字符“转换”为整数(反之亦然)。

也许是我的失明,但我看到的弊大于利。

顺便说一句,已经有一个与该主题相关的问题,但似乎没有给出正当理由,除了“他们决定如此”或“还不错”。

Implicit Type cast in C#

非常感谢您。

【问题讨论】:

  • 再读一遍:stackoverflow.com/a/1504959/284240 from "为什么存在从 char 到 int 的隐式转换?"
  • 好吧,如果你对answer from Eric Lippert不满意,那么......
  • 这只是一个糟糕的设计决定。 IMO 它应该是一个明确的转换。重载char + int -> charchar - char -> int 可以很好地解决将char 视为数字的常见情况,而不会引入这些问题。
  • @Tim:我读过,但仍然找不到我上面显示的误导性表达的正当理由。你能告诉我一些“巨大”好处的例子吗?

标签: c# .net casting char implicit-conversion


【解决方案1】:

基本上我在这里看到了一个好处,我不认为这是一个糟糕的设计决策。内部字符也是整数。基于等价表的数字和字符之间的转换称为编码

但是在 .NET 中,字符和字符串是 unicode encoded。 unicode 中的前 128 个字符等于前面的ASCII encoding

如果您想将字符串转换为数字(或返回),当您假设字符也是数字时,这可以很容易地完成。想象一下这样的事情:

char c = '1';
int i = Convert.ToInt32(c);

数字字符和数字表示之间的偏移总是0x30。现在可以在内部编写如下内容:

int result = c - 0x30;

if (result < 0 || result > 9)
    throw new InvalidCastException();

请注意,该示例适用于字符,因为 1 个字符只能包含 1 个数字文字(0 到 9)。对于字符串,您还需要将字符的索引乘以 10 和结果并将其添加到整体结果值中。

当然,这很像它“在幕后”工作。但是对于实践,将operator+(或减号)用于字符串或字符是不好的设计。这还有另一个原因。想象一下下面的代码:

string s1 = "Hello";
string s2 = " ";
string s3 = "World";

string helloWorld = s1 + s2 + s3;

当调用operator+ 时,会发生以下情况:

  1. 为字符串 1 的长度加上字符串 2 的长度分配内存。
  2. 将字符串一复制到新分配的数组的前面。
  3. 将字符串 2 复制到新分配的数组的后面。
  4. 返回新字符串的实例。

这会发生两次,所以你会有一个临时的字符串实例,给垃圾收集器带来压力。由于这个例子很简单,可能并不多,但我也发现了很多代码示例这样的字符串:

string sql = "SELECT " + c1 + ", " + c2 + 
    " FROM " + table + 
    " WHERE " + c1 + " = " + condition + ";";

也许编译器会优化这段代码,但你不能依赖他。在这种情况下,我更喜欢 @987654323@ 的包装器,或者至少在内部使用 StringBuilder@987654324@

得出一个结论: 从字符到整数的隐式转换有助于简化编码,但在构建字符串或字符时不应使用加号或减号。

【讨论】:

  • 为什么偏移量总是0x30?我认为这值得一票。
  • @stt106:因为它是在 ASCII 标准中定义的 (en.wikipedia.org/wiki/ASCII#ASCII_printable_code_chart)
  • 好的,谢谢。应该考虑一下,因为 int 48 (0x30) 代表 char '0'...顺便说一下,您不需要在 char 上调用 Convert.ToInt32,因为 c# 允许从 char 到 int 的隐式转换。
【解决方案2】:

尝试回答“为什么隐式提升到 32 位”部分:无论如何,CPU 在其寄存器中运行 32 位或 64 位整数。这意味着硬件会进行隐式提升。该语言尽量不抽象硬件。

也就是说,这可能很烦人。

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 2013-10-05
    • 2013-03-20
    • 1970-01-01
    • 2013-04-02
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    相关资源
    最近更新 更多