【问题标题】:What is the difference between String and string in C#?C#中的字符串和字符串有什么区别?
【发布时间】:2010-09-17 22:23:28
【问题描述】:

示例(注意大小写):

string s = "Hello world!";
String s = "Hello world!";

每种方法的使用指南是什么?又有什么区别?

【问题讨论】:

  • @ORMapper,但事实仍然是 string 是 C# grammar词法 构造,而 System.String 只是一个类型.不管任何规范中提到的任何 显式 差异,仍然存在这种隐含的差异,可以通过一些模糊性来适应。语言本身必须以某种方式支持string,使得实现不(相当)有义务考虑 BCL 中的特定类。
  • @KirkWoll:根据语言规范,语言本身必须认为string 与BCL 类型System.String 完全相同,仅此而已。这一点也不含糊。当然,您可以使用 C# 语法实现您自己的编译器,并将找到的所有标记用于任意的东西,与 C# 语言规范中定义的内容无关。但是,生成的语言只会与 C# 相似,不能被视为 C#。
  • 您可以使用string,而不需要系统的 using 指令。 String 无法做到这一点。
  • 对于来自 Algol 和 Fortran 的人来说,这个讨论表明 string 有问题。需要缩写System.String,但是,作为别名,它看起来很像,但并不完全相同。不过,经过几年的 C#,我想说,简单地使用 stringstring.Format() 是安全的,而不必担心 System.String
  • @Sangeeta 你在说什么? System.String 类仍然存在,string 关键字仍然是它的别名。就像System.Int32int。它们实际上是一回事。

标签: c# .net string types alias


【解决方案1】:

string 是 C# 中 System.String 的别名。
所以从技术上讲,没有区别。就像int vs. System.Int32

就准则而言,通常建议您在提及对象时使用string

例如

string place = "world";

同样,如果您需要专门引用该类,我认为一般建议使用String

例如

string greet = String.Format("Hello {0}!", place);

这是微软在their examples中倾向于使用的风格。

这方面的指导似乎已经改变,因为StyleCop 现在强制使用 C# 特定别名。

【讨论】:

  • 如果你决定使用 StyleCop 并遵循它,那就是说使用特定于语言的类型。因此对于 C#,您将拥有 string(而不是 String)、int(而不是 Int32)、float(而不是 Single)-stylecop.soyuz5.com/SA1121.html
  • 我总是使用别名,因为我假设有一天它可能会派上用场,因为它们充当抽象,因此可以在我不必知道的情况下更改它们的实现。
  • Visual Studio 2015 说 String.Format 应该改成 string.Format,所以我猜微软是这样的。我也一直使用 String 作为静态方法。
  • 您如何看待您可以定义自己的类型“String”但不能对“string”做同样的事情,因为它是一个关键字,如@9​​87654327@中所述
  • 我想那么...只要保持一致。在特定情况下使用字符串或字符串或使用某些字符串,但总是在这种情况下。
【解决方案2】:

System.String 是 .NET 字符串类 - 在 C# 中 stringSystem.String 的别名 - 所以在使用中它们是相同的。

至于指导方针,我不会太拘泥于任何你觉得喜欢的东西 - 生活中有更重要的事情,无论如何代码都是一样的。

如果您发现自己构建的系统需要指定您正在使用的整数的大小,因此倾向于使用Int16Int32UInt16UInt32 等,那么它可能看起来更多使用String 很自然——当在不同的.net 语言之间移动时,它可能会让事情更容易理解——否则我会使用字符串和整数。

【讨论】:

    【解决方案3】:

    小写的stringSystem.String 的别名。 它们在C# 中是相同的。

    关于您应该使用系统类型(System.Int32System.String 等)类型还是 C# aliasesintstring 等)类型存在争议。我个人认为你应该使用C# aliases,但这只是我个人的偏好。

    【讨论】:

    • 这就是问题所在,它们不是“C#”别名,而是“C”别名。 C# 语言中没有原生的“字符串”或“整数”,只有语法糖。
    • 不确定“C”从何而来,因为 C# 5 语言规范显示“关键字字符串只是预定义类 System.String 的别名。”在第 85 页,第 4.2.4 段。所有高级语言都是 CPU 指令集和字节码的语法糖。
    【解决方案4】:

    我听说过在 C# 中使用提供的类型别名的最佳答案来自 Jeffrey Richter 在他的书 CLR Via C# 中。以下是他的 3 个原因:

    • 我看到许多开发人员感到困惑,不知道在他们的代码中是使用 string 还是 String。因为在 C# 中,字符串(关键字)完全映射到 System.String(FCL 类型),所以没有区别,都可以使用。
    • 在 C# 中,long 映射到 System.Int64,但在不同的编程语言中,long 可以映射到 Int16 Int32。事实上,C++/CLI 实际上将 long 视为 Int32。如果他或她习惯于使用不同的编程语言进行编程,那么阅读一种语言的源代码的人很容易误解代码的意图。事实上,大多数语言甚至不会将 long 视为关键字,也不会编译使用它的代码。
    • FCL 有许多将类型名称作为其方法名称一部分的方法。例如,BinaryReader 类型提供了 ReadBooleanReadInt32ReadSingle 等方法,而System.Convert 类型提供了 ToBooleanToInt32ToSingle 等方法。虽然写下面的代码是合法的,但是有float的那一行对我来说感觉很不自然,看不出这行是否正确:
    BinaryReader br = new BinaryReader(...);
    float val  = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
    

    所以你有它。我认为这些都是非常好的观点。然而,我发现自己没有在自己的代码中使用 Jeffrey 的建议。也许我太拘泥于我的 C# 世界,但我最终试图让我的代码看起来像框架代码。

    【讨论】:

      【解决方案5】:

      这是一个约定俗成的问题,真的。 string 看起来更像 C/C++ 风格。一般约定是使用您选择的语言提供的任何快捷方式(int/Int for Int32)。这也适用于“对象”和decimal

      从理论上讲,这有助于将代码移植到未来的 64 位标准中,其中“int”可能意味着 Int64,但这不是重点,我希望任何升级向导都能将任何 int 引用更改为 @ 987654326@ 无论如何只是为了安全。

      【讨论】:

        【解决方案6】:

        有一个区别 - 如果没有using System;,则不能使用String

        【讨论】:

          【解决方案7】:

          出于格式化原因,我更喜欢大写的 .NET 类型(而不是别名)。 .NET 类型的颜色与其他对象类型相同(毕竟值类型是正确的对象)。

          条件和控制关键字(如ifswitchreturn)是小写的,颜色为深蓝色(默认情况下)。而且我宁愿没有使用和格式的分歧。

          考虑:

          String someString; 
          string anotherString; 
          

          【讨论】:

            【解决方案8】:

            使用系统类型可以更轻松地在 C# 和 VB.Net 之间进行移植,如果您喜欢这类事情的话。

            【讨论】:

              【解决方案9】:

              stringString 在所有方面都是相同的(除了大写的“S”)。两种方式都不会影响性能。

              由于语法突出显示,大多数项目中首选小写string

              【讨论】:

                【解决方案10】:

                string 只是System.String 的别名。编译器会一视同仁。

                唯一实际的区别是你提到的语法突出显示,如果你使用String,你必须写using System

                【讨论】:

                • 你不需要在 System 前加上前缀来使用 String。
                • 使用String时必须包含using System,否则会出现以下错误:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
                【解决方案11】:

                String 代表System.String,它是一个 .NET Framework 类型。 stringSystem.String 在 C# 语言中的别名。两者都编译成System.String in IL(Intermediate Language),所以没有区别。选择你喜欢的并使用它。如果您使用 C# 编写代码,我更喜欢 string,因为它是 C# 类型别名,并且为 C# 程序员所熟知。

                (int, System.Int32) 等我也可以这么说。

                【讨论】:

                • 我个人更喜欢使用“Int32”,因为它会立即显示值的范围。想象一下,如果他们在后来的更高位系统上升级了“int”类型。 c中的'int'显然被视为“目标处理器最有效地使用的整数类型”,并定义为“至少16位”。我希望那里有可预测的一致性,非常感谢。
                • @MyDaftQuestions 我同意。如果有什么意义的话,始终使用 .net 类型,因为它们不了解语言,而且类型很明显,独立于任何语言(我知道 F# 或 VB 的所有特性吗?)。跨度>
                • @Nyerguds 有两个理由根本不用担心它。一是int 在 C# 语言规范中定义为 32 位整数,与硬件无关。 C#,尽管在时间的迷雾中有着共同的传统,但实际上并不是 C。将 int 更改为 64 位整数将是规范和语言的重大变化。它还需要重新定义long,因为long 当前是64 位整数。另一个不用担心的原因是无关紧要的,因为类型永远不会改变,但 .NET 足够抽象,以至于 99% 的时间你都不必考虑它。 ;-)
                • @Craig 我深入研究了许多旧的专有游戏格式,但我确实必须一直考虑这些。然后使用Int16Int32Int64 在代码中比使用相当不具描述性的shortintlong 更透明很多
                • 但 short、not、long、float、double 等 都是描述性的,因为它们在语言规范中。 C# 不是 C。我更喜欢在声明中使用它们,因为它们简洁、小巧且美观。我确实更喜欢 API 上的 Torre 库名称,其中 API 具有数据类型依赖性。
                【解决方案12】:

                两者都是一样的。但从编码指南的角度来看,最好使用string 而不是String。这是开发人员通常使用的。例如而不是使用Int32 我们使用int 因为intInt32 的别名

                仅供参考 “关键字字符串只是预定义类System.String 的别名。” - C# 语言规范 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx

                【讨论】:

                  【解决方案13】:

                  为了完整起见,这里是相关信息的脑转储......

                  正如其他人所指出的,stringSystem.String 的别名。假设您的代码 using String 编译为 System.String(即,您没有针对具有不同 String 类型的其他命名空间的 using 指令),它们编译为相同的代码,因此在执行时没有区别任何。这只是 C# 中的别名之一。完整列表如下:

                  object:  System.Object
                  string:  System.String
                  bool:    System.Boolean
                  byte:    System.Byte
                  sbyte:   System.SByte
                  short:   System.Int16
                  ushort:  System.UInt16
                  int:     System.Int32
                  uint:    System.UInt32
                  long:    System.Int64
                  ulong:   System.UInt64
                  float:   System.Single
                  double:  System.Double
                  decimal: System.Decimal
                  char:    System.Char
                  

                  除了stringobject,别名都是值类型。 decimal 是值类型,但不是 CLR 中的原始类型。唯一没有别名的原始类型是System.IntPtr

                  在规范中,值类型别名被称为“简单类型”。字面量可用于每个简单类型的常量值;没有其他值类型具有可用的文字形式。 (将此与 VB 进行比较,它允许 DateTime 文字,并且也有一个别名。)

                  在一种情况下必须使用别名:显式指定枚举的基础类型时。例如:

                  public enum Foo : UInt32 {} // Invalid
                  public enum Bar : uint   {} // Valid
                  

                  这只是规范定义枚举声明的方式的问题 - 冒号后面的部分必须是 integral-type 产生式,它是 sbytebyte 的一个标记, shortushortintuintlongulongchar... 与变量声明所使用的 type 产生式相反.它不表示任何其他差异。

                  最后,关于使用哪个:就我个人而言,我在任何地方都使用别名来实现,但任何 API 都使用 CLR 类型。就实施而言,您使用哪种方式真的无关紧要 - 团队之间的一致性很好,但没有其他人会关心。另一方面,如果您在 API 中引用一个类型,那么您必须以一种语言中立的方式进行,这一点非常重要。名为ReadInt32 的方法是明确的,而名为ReadInt 的方法需要解释。例如,调用者可能使用为Int16 定义int 别名的语言。 .NET 框架设计者遵循了这种模式,在 BitConverterBinaryReaderConvert 类中就是很好的例子。

                  【讨论】:

                    【解决方案14】:

                    上面已经介绍过了;但是,您不能在反射中使用string;你必须使用String

                    【讨论】:

                    • 我不明白这个答案是什么意思以及为什么它被赞成。您可以在反射中使用typeof(string)。示例一:if (someMethodInfo.ReturnType == typeof(string)) { ... } 示例二:var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance); 哪里必须使用String,而不是string?如果您尝试Type.GetType("String")Type.GetType("string") 之类的方法,则由于缺少命名空间,两者都不会找到该类。如果出于某种愚蠢的原因,您以区分大小写的方式将某个类型的 .Name"string" 进行比较,那么您是对的。
                    【解决方案15】:

                    正如其他人所说,他们是一样的。默认情况下,StyleCop 规则将强制您使用 string 作为 C# 代码样式的最佳实践,除非引用 System.String 静态函数,例如 String.FormatString.JoinString.Concat 等...

                    【讨论】:

                      【解决方案16】:

                      string 是保留字,但String 只是一个类名。 这意味着string 本身不能用作变量名。

                      如果出于某种原因你想要一个名为 string 的变量,你只会看到这些编译中的第一个:

                      StringBuilder String = new StringBuilder();  // compiles
                      StringBuilder string = new StringBuilder();  // doesn't compile 
                      

                      如果你真的想要一个名为 string 的变量名,你可以使用 @ 作为前缀:

                      StringBuilder @string = new StringBuilder();
                      

                      另一个关键区别:Stack Overflow 以不同的方式突出显示它们。

                      【讨论】:

                        【解决方案17】:

                        C#是一种与CLR一起使用的语言。

                        string 是 C# 中的一种类型。

                        System.String 是 CLR 中的一个类型。

                        当你将 C# 与 CLR 一起使用时,string 将被映射到 System.String

                        理论上,您可以实现生成 Java 字节码的 C# 编译器。该编译器的合理实现可能会将 string 映射到 java.lang.String 以便与 Java 运行时库进行互操作。

                        【讨论】:

                          【解决方案18】:

                          我只想将此添加到来自 Ritchers 书中的 lfousts 答案:

                          C# 语言规范指出,“就风格而言,优先使用关键字 使用完整的系统类型名称。”我不同意语言规范;我更喜欢 使用 FCL 类型名称并完全避免原始类型名称。其实我希望 编译器甚至没有提供原始类型名称,并迫使开发人员使用 FCL 而是键入名称。以下是我的理由:

                          • 我看到许多开发人员感到困惑,不知道是否使用 stringString 在他们的代码中。因为在 C# 中 string (关键字)正好映射到 System.String(FCL 类型),没有区别,都可以使用。相似地, 我听一些开发者说 int 在应用程序时代表一个 32 位整数 在 32 位操作系统上运行,并且它在应用程序时表示一个 64 位整数 在 64 位操作系统上运行。这句话是绝对错误的:在 C# 中,一个 int 总是映射 System.Int32,因此它表示一个 32 位整数,与操作系统无关 代码正在运行。如果程序员会在他们的代码中使用 Int32,那么这种潜力 也消除了混乱。

                          • 在 C# 中,long 映射到 System.Int64,但在不同的编程语言中,long 可以映射到 Int16Int32。事实上,C++/CLI 确实将 long 视为 Int32。 以一种语言阅读源代码的人很容易误解代码的 如果他或她习惯于使用不同的编程语言进行编程,则意图。 事实上,大多数语言甚至不会将 long 视为关键字,也不会编译代码 使用它。

                          • FCL 有许多将类型名称作为其方法名称一部分的方法。为了 例如,BinaryReader 类型提供了诸如 ReadBooleanReadInt32ReadSingle 等,System.Convert 类型提供诸如 ToBooleanToInt32ToSingle 等。尽管写以下内容是合法的 代码,带有float的那一行我感觉很不自然,而且这行不是很明显 正确:

                            BinaryReader br = new BinaryReader(...);
                            float val = br.ReadSingle(); // OK, but feels unnatural
                            Single val = br.ReadSingle(); // OK and feels good
                            
                          • 许多专门使用 C# 的程序员往往会忘记其他编程 可以对 CLR 使用语言,正因为如此,C#-isms 潜入 类库代码。例如,微软的 FCL 几乎完全是用 C# 编写的,并且 FCL 团队的开发人员现在已经将方法引入到库中,例如 ArrayGetLongLength,它返回一个 Int64 值,它在 C# 中是 long 但不是 其他语言(如 C++/CLI)。另一个例子是 System.Linq.EnumerableLongCount 方法。

                          在我阅读完整的段落之前,我没有得到他的意见。

                          【讨论】:

                            【解决方案19】:

                            String 不是关键字,可以用作标识符,而string 是关键字,不能用作标识符。并且在功能上两者是相同的。

                            【讨论】:

                              【解决方案20】:

                              与其他程序员的常见做法相反,我更喜欢 String 而不是 string,只是为了强调 String 是一个引用类型这一事实,正如 Jon Skeet 所提到的那样。

                              【讨论】:

                              • 好点。如果没有发明“字符串”,我们不会有任何混淆,也不需要这种毫无意义的讨论。我们所有的应用程序都可以使用 String 运行良好。如果您不关心位大小,'int' 似乎很有用,这在大多数情况下都会发生,而 'string' 似乎只是为了保持一致性而添加。
                              【解决方案21】:

                              两者之间没有区别 - string,但在考虑其他开发人员的源代码时似乎是首选。

                              【讨论】:

                                【解决方案22】:

                                stringSystem.String 的别名(或简写)。这意味着,输入string 是指System.String。您可以阅读更多思考链接:'string' is an alias/shorthand of System.String.

                                【讨论】:

                                  【解决方案23】:

                                  没有区别。

                                  C# 关键字 string 映射到 .NET 类型 System.String - 它是一个符合语言命名约定的别名。

                                  同样,int 映射到 System.Int32

                                  【讨论】:

                                    【解决方案24】:

                                    String (System.String) 是基类库中的一个类。 string(小写)是 C# 中的保留作品,是 System.String 的别名。 Int32 与 int 的情况与Boolean vs. bool 类似。这些 C# 语言特定的关键字使您能够以类似于 C 的样式声明原语。

                                    【讨论】:

                                      【解决方案25】:

                                      聚会迟到:我 100% 的时间都使用 CLR 类型(好吧,除非 强制 使用 C# 类型,但我不记得上次是什么时候)。

                                      根据 Ritchie 的 CLR 书籍,我最初是在几年前开始这样做的。对我来说,所有 CLR 语言最终都必须能够支持一组 CLR 类型是有道理的,因此自己使用 CLR 类型可以提供更清晰、可能更“可重用”的代码。

                                      现在我已经这样做了多年,这是一种习惯,我喜欢 VS 为 CLR 类型显示的颜色。

                                      唯一真正令人沮丧的是自动完成使用 C# 类型,因此我最终重新键入自动生成的类型以指定 CLR 类型。

                                      另外,现在,当我看到“int”或“string”时,我觉得它真的很不对劲,就像我在看 1970 年代的 C 代码一样。

                                      【讨论】:

                                        【解决方案26】:

                                        其他地方没有提到的一个论点是更喜欢帕斯卡案例String

                                        System.String 是一个引用类型,引用类型名称按约定是帕斯卡大小写

                                        【讨论】:

                                        • -1 按照惯例,所有类型名称都是帕斯卡大小写。但是C#关键字都是小写的。
                                        • @PDaddy 是的,string 确实是 C# 关键字。这里要问的问题是更喜欢关键字还是类型名称。我的回答是,尽管您显然可以选择关键字,但支持使用类型名称的一个论据是它们关键字 string,它是 String 的别名,最终是一个引用类型。关键字 @987654326相比之下,@ 是 Int32 的别名,它是一种值类型。
                                        • 引用类型和值类型之间的大小写约定没有区别,正如您自己提到的 Int32 类型所证明的那样。为了遵守一些想象的限制,即引用类型遵循与值类型不同的命名约定,避开关键字以支持类名是没有意义的。
                                        • @PDaddy 是的,你是对的。我在这里继承了 Java 约定,其中原语是 camelCase。
                                        【解决方案27】:

                                        String 指的是一个字符串对象,它带有用于操作包含的字符串的各种函数。

                                        string 指原始类型

                                        在 C# 中它们都编译为 String,但在其他语言中它们不会,因此如果要处理 String 对象,则应使用 String,如果要处理文字,则应使用 string。

                                        【讨论】:

                                        • 注意命名这些其他语言,因为我知道 .net 中没有字符串!= System.String。此外,文字与字符串与字符串无关...
                                        • 真的有 26 位选民认为这是正确的吗?
                                        【解决方案28】:

                                        是的,它们之间没有区别,就像boolBoolean

                                        【讨论】:

                                          【解决方案29】:

                                          Daniel Solis' book 引用了这个问题。

                                          所有预定义的类型都直接映射到 底层 .NET 类型。 C# 类型名称(字符串)只是 .NET 类型(String 或 System.String),因此使用 .NET 名称在语法上可以正常工作,尽管 这是不鼓励的。在 C# 程序中,您应该使用 C# 名称 而不是 .NET 名称。

                                          【讨论】:

                                            【解决方案30】:

                                            This YouTube 视频实际演示了它们的不同之处。

                                            但现在是一个很长的文字答案。

                                            当我们谈论.NET 时,有两种不同的东西,一种是.NET 框架,另一种是使用该框架的语言(C#VB.NET 等)。

                                            System.String”又名“String”(大写“S”)是 .NET 框架数据类型,而“string”是 C# 数据类型。

                                            简而言之,“字符串”是“字符串”的别名(相同的东西用不同的名称称呼)。所以从技术上讲,下面的两个代码语句都会给出相同的输出。

                                            String s = "I am String";
                                            

                                            string s = "I am String";
                                            

                                            同理,其他C#数据类型也有别名,如下所示:

                                            object:System.Object,string:System.String,bool:System.Boolean,byte:System.Byte,sbyte:System.SByte,short:System.Int16等等。

                                            现在从程序员的角度来看一个价值百万美元的问题:那么什么时候使用“String”和“string”?

                                            避免混淆的第一件事是始终如一地使用其中一个。但从最佳实践的角度来看,当您进行变量声明时,最好使用“string”(小“s”),当您将其用作类名时,首选“String”(大写“S”)。

                                            在下面的代码中,左边是一个变量声明,它是使用“字符串”声明的。在右边,我们调用了一个方法,所以“String”更合理。

                                            string s = String.ToUpper() ;
                                            

                                            【讨论】:

                                            • 但是现在一行有两种样式? :)
                                            • 你的部分答案的一个小问题:'string'是'System.String'的别名,而不是相反。
                                            猜你喜欢
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2010-10-18
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2011-02-26
                                            相关资源
                                            最近更新 更多