C#中的String和string有什么区别?

7511

这两者之间有什么不同,我应该使用哪一个?

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

110
@O.R.Mapper,事实仍然存在,string 是 C# 语法的一个 词法 构造,而 System.String 只是一种类型。无论任何规范中提到的 显式 差异如何,仍然存在这种隐含的差异,可能会带来一些歧义。语言本身必须以一种不需要考虑 BCL 中的特定类的方式支持 string - Kirk Woll
146
根据语言规范,该语言本身必须将“string”视为与BCL类型“System.String”完全相同,没有任何其他含义。这一点毫不含糊。当然,你可以使用C#语法实现自己的编译器,并使用找到的所有标记来执行任意的、与C#语言规范定义无关的操作。然而,结果得到的语言只能被视为类似于C#,而不能被视为C#本身。 - O. R. Mapper
125
对于System命名空间的string类型,您无需使用using指令即可直接使用,但是对于String类型则不行。 - Wilsu
27
对于来自Algol和Fortran的人来说,这个讨论表明string存在问题。需要缩写System.String,但作为别名,它看起来非常相似,但不完全相同。然而,经过几年的C#编程,我认为,安全起见,可以直接使用stringstring.Format(),不用担心System.String - Roland
27
@Sangeeta你在说什么?System.String类还在,而string关键字仍然是它的别名,就像System.Int32int一样。它们实际上是同一个东西。 - Craig Tullis
显示剩余11条评论
67个回答

222

这个YouTube视频演示了它们之间的实际区别。

但是现在给出一个长篇回答。

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

enter image description here

"System.String"也称为"String"(大写"S")是.NET框架数据类型,而"string"是C#数据类型。

enter image description here

简而言之,“String”是“string”的别名(用不同的名称指代同一事物)。因此,下面两个代码语句在技术上将输出相同的结果。

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"。

string s = String.ToUpper() ;

217

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

string 是 C# 中的一种类型。

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

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

理论上,你可以实现一个生成 Java 字节码的 C# 编译器。这个编译器的明智实现可能会将 string 映射为 java.lang.String,以便与 Java 运行时库进行互操作。


194

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

关于是否应该使用系统类型(System.Int32, System.String等)还是C#别名(int, string等)有争议。我个人认为你应该使用C#别名,但这只是我的个人偏好。


7
问题在于,它们不是'C#'的别名,而是'C'的别名。C#语言中没有本地的'string'或'int',只是语法糖。 - Quark Soup
20
不确定这里的 "C" 来自何处,因为 C# 5 语言规范在第85页第4.2.4段中写道:“关键字string只是预定义类System.String的别名。”所有高级语言都是基于 CPU 指令集和字节码的语法糖。 - aiodintsov

173

string只是System.String的别名。编译器会将它们视为相同。

唯一的实际区别就是语法高亮,正如您所提到的,并且如果使用String,您必须编写using System


21
在使用String时,您必须包括using System,否则会出现以下错误:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?) - Ronald

161

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

“关键字 string 只是预定义类 System.String 的别名。”- C# Language Specification 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx


2
链接失效。新链接 - C# 6.0 规范 8.2.5. - woojiq

135

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


126

6年5个月之后有一个新的答案(拖延症)。

string是C#中的保留关键字,它始终具有固定含义,但String只是一个普通的标识符,可以指代任何东西。取决于当前类型的成员、当前命名空间和应用的using指令及其位置,String可能是与global::System.String不同的值或类型。

我将提供两个示例,其中using指令无法帮助解决问题


首先,当String是当前类型(或本地变量)的时:

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

  void Example()
  {
    var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
  }
}
上述代码无法编译,因为 IEnumerable<> 没有名为Format的非静态成员,并且没有应用扩展方法。在上述情况下,可能仍然可以在其他语法上只能使用类型的情况下使用String。例如:String local = "Hi mum!"; 可以正常工作(取决于命名空间和using指令)。
更糟的是: 如果写成 String.Concat(someSequence),则可能会转到 Linq 扩展方法Enumerable.Concat (取决于using指令)。它不会进入静态方法string.Concat
其次,在当前类型中嵌套另一个类型时使用String
class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

Example 方法中的两个语句都无法编译通过。这里的 String 总是一个钢琴,即 MyPiano.String。它上面没有(静态或非静态)成员 Format 存在,也不会从其基类继承而来。而值 "Goodbye" 无法转换为它。


1
你的例子有点牵强,但只是有点。我认为这两个例子都表明了设计问题,但在遗留代码中这是很可能的。 - ClickRick
当然,如果你有一个名为string的变量,事情也无法编译。 - Paŭlo Ebermann
这样的名称在C#中必须写成@string。它表示将string视为普通标识符(而不是关键字)。不建议使用类似@string的名称,但如果您需要访问在另一种.NET语言中编写的名称不是特殊的string成员,则@技巧变得有用。 - Jeppe Stig Nielsen

109

使用系统类型可以更轻松地在 C# 和 VB.Net 之间移植,如果您对此感兴趣的话。


98

与其他程序员的常规做法相反,我更喜欢使用String而非string,这样可以突出显示String是一种引用类型。这正如Jon Skeet所提到的那样。


好观点。如果没有发明“字符串”,我们就不会有任何混淆,也不需要这个毫无意义的讨论。所有我们的应用程序都可以使用String正常运行。“int”似乎很有用,如果您不关心位大小,这种情况大多数时候都会发生,“string”似乎只是为了保持一致性而添加的。 - Roland

92

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接