Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从字符到单个字符串的隐式转换_C#_.net_Implicit Conversion_Language Design - Fatal编程技术网

C# 从字符到单个字符串的隐式转换

C# 从字符到单个字符串的隐式转换,c#,.net,implicit-conversion,language-design,C#,.net,Implicit Conversion,Language Design,首先:我知道如何解决这个问题。我不是在寻找解决办法。我对设计选择背后的推理感兴趣,这些设计选择导致了一些隐式转换,而没有导致其他转换 今天我在我们的代码库中遇到了一个很小但很有影响的错误,其中一个int常量是用同一个数字的char表示形式初始化的。这导致ASCII将char转换为int。大概是这样的: char a = 'a'; int z = a; Console.WriteLine(z); // Result: 97 我很困惑为什么C#会允许这样的事情。在四处搜索后,我发现了以下问

首先:我知道如何解决这个问题。我不是在寻找解决办法。我对设计选择背后的推理感兴趣,这些设计选择导致了一些隐式转换,而没有导致其他转换

今天我在我们的代码库中遇到了一个很小但很有影响的错误,其中一个
int
常量是用同一个数字的
char
表示形式初始化的。这导致
ASCII
char
转换为
int
。大概是这样的:

char a = 'a';
int z = a;
Console.WriteLine(z);    
// Result: 97
我很困惑为什么C#会允许这样的事情。在四处搜索后,我发现了以下问题,并由Eric Lippert本人给出了答案:

摘录:

然而,我们可以做出有根据的猜测,为什么是含蓄的 char to ushort被认为是个好主意。这里的关键思想是 从数字到字符的转换是“可能不可靠的” 转换。它拿走了你不知道的东西 成为一个角色,并选择将其视为一个角色。这似乎是最重要的 你想大声说你在做什么, 而不是意外地允许它。但反过来要少得多 狡猾的。在C语言编程中,有一个处理 字符作为整数——获取其基础值,或 数学在他们身上

我可以同意它背后的理由,尽管IDE提示会很棒。然而,我有另一种情况,即隐式转换突然变得不合法:

在我看来,这种转变是非常合乎逻辑的。这不会导致数据丢失,作者的意图也非常清楚。同样,在我阅读了关于
char
int
隐式转换的其余答案后,我仍然看不到任何不合法的理由

这就引出了我的实际问题:


C#设计团队有什么理由不执行从
char
string
的隐式转换,而从外观上看它是如此明显(特别是当将它与
char
int
转换进行比较时)。

当您将
char
转换为
int
时,您不仅要更改其“类型”,还要在ASCII表中获取其“索引”,这是一件完全不同的事情,它们不允许您“将字符转换为int”,而是为您提供了一个有用的数据,以满足可能的需要

为什么不将
字符
转换为
字符串

因为它们实际上代表了很多不同的东西,并且以一种非常不同的方式存储


char和string不是表示同一事物的两种方式。

char
是一种值类型。不,它不像
int
或double那样是数字,但它仍然派生自
System.ValueType
。然后,堆栈上存在一个
char
变量


String
是一种引用类型。所以它生活在堆上。如果要将值类型用作引用类型,则需要先将其框起来。编译器需要确保您知道通过装箱正在做什么。所以,你不能有一个隐含的演员阵容。

首先,正如我经常说的,当有人问关于C#的“为什么不?”问题时:设计团队不必提供不做某个功能的理由。特性需要花费时间、精力和金钱,而您所做的每一个特性都需要花费时间、精力和金钱才能获得更好的特性

但我不想马上拒绝这个前提;这个问题可以更好地表述为“这个建议的功能的设计优缺点是什么?”

这是一个完全合理的特性,并且有一些语言允许您将单个字符视为字符串。(Tim在评论中提到VB,Python也将字符和一个字符串视为可互换的IIRC。我肯定还有其他的。)然而,如果我对该功能进行了介绍,我会指出一些缺点:

  • 这是拳击转换的一种新形式。char是廉价的值类型。字符串是堆分配的引用类型。装箱转换可能会导致性能问题并产生收集压力,因此有一种观点认为它们应该在程序中更可见,而不是更少可见
  • 该功能不会被视为“字符可转换为一个字符串”。它将被用户视为“字符是一个字符串”,现在提出大量的连串问题是完全合理的,比如:可以调用字符
    .Length
    ?如果我可以将字符传递给需要
    字符串的方法,并且可以将字符串传递给需要
    IEnumerable
    的方法,那么我可以将
    字符传递给需要
    IEnumerable
    的方法吗?那似乎。。。古怪的我可以在字符串上调用
    Select
    Where
    ;我可以用一个字符吗?这似乎更奇怪。建议的功能所做的只是移动你的问题;如果实现了它,您现在可能会问“为什么我不能在字符上调用Select?”或者类似的问题

  • 现在将前两点结合起来。如果我把字符看作一个字符串,然后我把一个字符转换成一个对象,我得到的是装箱字符还是字符串

  • 我们还可以进一步推广第二点。字符串是字符的集合。如果我们要说一个字符可以转换为一组字符,为什么不使用字符串呢?为什么不说char也可以用作
    列表
    ?为什么要停止使用
    char
    ?我们应该说
    int
    可以转换为
    IEnumerable
  • 我们可以进一步概括:如果有一个从char到字符串中chars-of-chars-in-string的明显转换,那么也有一个从char到
    Task
    的明显转换——只需创建一个返回char的已完成任务——到
    Func
    ——只需创建一个
    char a = 'a';
    string z = a; // CS0029 Cannot implicitly convert type 'char' to 'string'