题 C#中字符串和字符串有什么区别?


示例(注意这个案子):

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

什么是 方针 供各自使用?什么是 分歧


5362


起源


@ O.R.Mapper,但事实仍然如此 string 是一个 词法 C#的构造 语法 而 System.String 只是一种类型。无论如何 明确的 在任何规范中提到的差异,仍然存在这种隐含的差异,可以容纳一些歧义。语言本身 必须 支持 string 在某种程度上,实施不是(非常)有义务考虑BCL中的特定类。 - Kirk Woll
@KirkWoll:根据语言规范,语言本身 必须 考虑 string 与BCL类型完全相同 System.String, 没有其他的。这根本不含糊。当然,您可以使用C#语法实现自己的编译器,并使用所有类似的标记来处理任意内容,与C#语言规范中定义的内容无关。但是,生成的语言只是C#外观,它不能被认为是C#。 - O. R. Mapper
您可以使用 string 没有System的using指令。你不能这样做 String。 - Wilsu
对于来自Algol和Fortran的人来说,这次讨论表明存在问题 string。需要缩写 System.String但是,作为一个别名,它看起来很像,但不完全相同。不过,经过几年的C#,我会说,使用它是安全的 string 和 string.Format() 而不用担心 System.String。 - Roland
如果在2017年提出这样的问题,它将收到4,000个downvotes,2,000个指向MSDN String类页面的链接,并且因为没有效率而关闭。 - IRGeekSauce


答案:


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

就指导方针而言,通常建议使用 string 任何时候你指的是一个物体。

例如

string place = "world";

同样,我认为通常建议使用 String 如果你需要专门参考这个班级。

例如

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

这是微软倾向于使用的风格 他们的例子

看来这个领域的指导可能已经改变了 了StyleCop 现在强制使用C#特定的别名。


5097



如果你决定使用StyleCop并遵循它,那就说要使用特定于该语言的类型。因此,对于C#,你将拥有字符串(而不是String),int(而不是Int32),float(而不是Single) - stylecop.soyuz5.com/SA1121.html - Dominic Zukiewicz
我总是使用别名,因为我假设有一天它可能会派上用场,因为它们充当抽象,所以因此可以在不必我知道的情况下改变它们的实现。 - Rob
Visual Studio 2015说String.Format应该改为string.Format,所以我猜微软就是这样。我也一直使用String作为静态方法。 - Sami Kuhmonen
正如我读过这些,我注意到有几条评论是不正确的。 @ DRAirey1随着时间的推移,您会发​​现旧的方式仍然是最好的,如果您怀疑我敢于尝试在不使用Visual Studio的情况下编写C#代码。这实际上是不可能的,并且在Web开发工作中不时会出现这种情况。 @Vlad你不需要导入任何东西来使用String。 @Abhi你的评论毫无意义,同样如此 string.Format()。 @KlitosG不,这不是真的。它们都完全相同。 - krowe2
您能否添加一条评论,实际上存在差异?例如: nameof(string) 不会编译而是 nameof(String) 将。 - Jeroen Vannevel


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

正如其他人所说, string 是别名 System.String。它们编译为相同的代码,因此在执行时没有任何区别。这只是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

除了 string 和 object,别名都是值类型。 decimal 是一种值类型,但不是CLR中的基本类型。唯一没有别名的原始类型是 System.IntPtr

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

你有一种情况  使用别名:明确指定枚举的基础类型时。例如:

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

这只是规范定义枚举声明的方式问题 - 冒号之后的部分必须是 整体式 生产,这是一个标志 sbytebyteshortushortintuintlongulongchar......而不是 类型 例如,变量声明使用的生产。它并不表示任何其他差异。

最后,当谈到使用它时:我个人在各处使用别名来实现,但是任何API都使用CLR类型。你在实施方面使用它并不重要 - 你的团队之间的一致性很好,但没有人会关心。另一方面,如果您在API中引用类型,则以语言中立的方式执行此操作,这一点非常重要。一种叫做的方法 ReadInt32 是明确的,而一种叫做的方法 ReadInt 需要解释。调用者可能正在使用定义的语言 int 别名 Int16, 例如。 .NET框架设计者已经遵循了这种模式,很好的例子就在于 BitConverterBinaryReader 和 Convert 类。


3037



枚举的继承情况很有趣。您是否可以指出为什么必须使用别名进行枚举的文档?或者这是一个已知的错误? - JaredPar
这是在规范的第14.1节(我不能轻易引用,因为它太长了)。它没有明确说明你必须使用别名,但别名是 有点 作为自己的类型对待。这有点奇怪。 - Jon Skeet
@PiPeep比大量的投票更令人震惊的是惊人的低数量的downvotes(考虑前5个帖子共有超过2000个upvotes,但其中只有1个downvote全部)。特别是当你考虑到任何社区中总是存在“仇恨”的概念时,我真的觉得这简直令人难以置信。 - corsiKa
一个有趣的区别 string 和 String 就是它 string' is a keyword in c#, so you can not use it as a variable name.For Ex: string string =“hi”;//compiler error, but String String =“hi”;`是可接受的,如 String 是一个识别而不是关键字。 - Sanjeev Rai
@SanjeevRai:是的。您可以使用 @string 创建一个最终为的标识符 string 虽然。这是一种逃避机制。 - Jon Skeet


String 代表 System.String 它是.NET Framework类型。 string 是别名 在C#语言中 System.String。它们都被编译为 System.String 在IL(中级语言),所以没有区别。选择你喜欢的并使用它。如果你用C#编码,我更喜欢 string 因为它是C#类型的别名,并且是C#程序员所熟知的。

我可以这么说 intSystem.Int32 等等..


608



`如果你用C#编码,我更喜欢字符串,因为它是C#类型的别名,而且是C#程序员所熟知的 - 当C#人不知道.NET框架的时候。 +1,因为我认为这是最好的答案,但我提到的这一点似乎很奇怪。 - MyDaftQuestions
我个人更喜欢使用“Int32”,因为它会立即显示值的范围。想象一下,如果他们在后来的更高位系统上升级了“int”的类型。 c中的'int'显然被视为 “目标处理器最有效的整数类型”,并定义为“至少16位”。我希望那里有可预测的一致性,非常感谢你。 - Nyerguds
@MyDaftQuestions我同意。如果有的话,它会有意义 始终使用.net类型 因为他们语言无知而且类型很明显,独立于任何语言(我是否都知道F#或VB的所有特性?)。 - Peter A. Schneider


我听说过在C#中使用提供的类型别名的最佳答案来自杰弗里里希特在他的书中 CLR通过C#。以下是他的3个理由:

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

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


411



第二点听起来实际上是一个原因 不 使用 string, int 等等 - MauganRa
@MauganRa本应该如此,这本书的作者列出了他为什么这样做的原因 不使用 别名。 - tomi.lee.jones
“如果有人正在阅读C#源代码,他们应该根据语言规范解释很久,而不是其他语言规范。”这完全忽略了这一点。这不是任何人 打算 如果一个类型具有与程序员在另一个环境中每天看到的不同的含义,那么对于一个人的大脑来说,错误地解释代码是很容易的。我们都会犯错;使用明确命名的类型会降低这些错误的可能性。 - Darryl
+这些原因总结了我对此事的看法。当我第一次开始用C#编写代码(来自Java / C ++ / C背景)时,我认为别名很难看。我仍然有这种感觉,不幸的是,世界上大多数人似乎并不赞同我,或者他们并不关心,所以使用小写字母。 - gusgorman
@jinzai的问题是关于C#,其中 long 无论平台还是编译器,都被定义为带符号的64位整数。所以至少在某些情况下,是的,它 不 取决于语言。 - phoog


string 是一个保留字,但是 String 只是一个班级名称。 这意味着 string 不能单独用作变量名。

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

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

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

StringBuilder @string = new StringBuilder();

另一个重要区别:Stack Overflow以不同的方式强调它们。


380



请记住,呼叫本地 @string 因为当地人的名字只出现在PDB中,所以实在是毫无意义。不妨称之为 _string 或者其他的东西。对于通过反射可以访问名称的东西更有意义,其中名称是 @string 会员会 "string"。 - Roman Starkov
另外请记住使用保留字作为变量名称是非常不优雅的。 - Elton
“堆栈溢出突出显示它们”。没有更多理由需要:) - Ole Albers
OP不希望使用String或string作为变量名。他们要求解释这些之间的区别 类型。你的回答只会增加IMO的混乱 - Matt Wilko


有一点不同  - 你不能使用 String 无 using System; 预先。


327



默认情况下,大多数人都会以任何方式在文件顶部添加此项。默认情况下,VS会在大多数情况下执行此操作! - IbrarMumtaz
默认情况下我只添加 using 我需要的陈述,并明确删除我没有的所有陈述。 Power Productivity Tools>“[x]删除并格式化保存时的使用” - JMD
@JMD我修改了.cs模板文件,所以它在顶部甚至没有任何using语句!我还将类模板更改为 internal sealed。 - ErikE


它已在上面介绍过;但是,你不能使用 string 反思;你必须使用 String


269





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

至于指导方针,我不会陷入困境,只是使用你想要的任何东西 - 生活中有更重要的事情,无论如何代码都是一样的。

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


204



+1表示生活中有更重要的事情,我觉得这是另一个StackOverflow数百万的关于a的upvote问题 不重要的 问题正在发生: en.wikipedia.org/wiki/Parkinson's_law_of_triviality - Sebastian
只需选择一个并保持一致。如果您在某个房屋风格的地方工作,请使用它。 - Alan B
不幸的是,样式是个人偏好,并且可能太昂贵,无法在没有专用代码所有者的情况下在多个团队的大型代码库中执行。总是有更重要的事情需要照顾而不是字符串vs String。这让我们回到“生活中更重要的事情” - aiodintsov


我更喜欢资本化 .NET 格式化原因的类型(而不是别名)。该 .NET 类型的颜色与其他对象类型相同(毕竟,值类型是适当的对象)。

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

考虑:

String someString; 
string anotherString; 

167



你也写代码如下:Int32 i = 1;而不是int i = 1; ?似乎不一致,在可用时不使用字符串别名。 - bytedev
@nashwan:实际上,是的,我确实使用过 Int32 i=1; 无论如何 int i = 1;  我发现前者对我的意图更具可读性:即我想要一个32位有符号整数。 - NotMe
嗯,我想这完全取决于开发人员是否认为他们正在编写C#代码(字符串)或.NET代码(字符串)。我个人认为我正在编写C#(而且它是使用.NET的C#)。 - bytedev
@Alex:我的观点很简单,我更喜欢在编码中非常具体,以消除歧义。 - NotMe
在光谱的绝对另一端,我几乎总是只使用 var - tic