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


6504

示例(注意情况):

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

每种使用的准则是什么?有什么区别?


72
@ORMapper,但事实仍然string是C#语法词汇构造,而仅仅是一种类型。不管任何规范中提到的任何显着差异,仍然存在这种隐含差异,可以通过一些歧义来解决。语言本身必须以某种方式支持该实现,而不是(非常)必须考虑BCL中的特定类。System.Stringstring
Kirk Woll 2014年

106
@KirkWoll:根据语言规范,该语言本身必须考虑string与BCL类型完全相同System.String,没有别的。那根本不是模棱两可的。当然,您可以使用C#语法实现自己的编译器,并使用所有发现的令牌将这些令牌用于与C#语言规范中定义的内容无关的任意内容。但是,结果语言只能是类似C#的语言,不能视为C#。
OR Mapper 2014年

88
您可以在string不使用using指令的情况下使用System。您无法使用来做到这一点String
Wilsu 2015年

14
对于来自Algol和Fortran的人,此讨论表明string。它需要缩写System.String,但作为别名,它看起来很像,但不完全相同。我想说,经过几年的C#工作后,简单使用stringstring.Format()不用担心是安全的System.String
罗兰

8
@Sangeeta你在说什么?该System.String班仍然存在,而string关键词仍然是它的别名。就像System.Int32int。他们实际上是同一件事。
Craig

Answers:


6102

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

就准则而言,通常建议string您在引用对象时使用任何时间。

例如

string place = "world";

同样,我认为String如果需要专门引用该类,通常建议使用。

例如

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

这是Microsoft倾向于在示例中使用的样式。

似乎此区域中的指南可能已更改,因为StyleCop现在强制使用C#特定别名。


163
如果您决定使用StyleCop并遵循该要求,那将意味着使用特定于该语言的类型。因此,对于C#,您将拥有字符串(而不是String),整数(而不是Int32),浮点数(而不是Single)-stylecop.soyuz5.com/SA1121.html
Dominic Zukiewicz 2012年

144
我总是使用别名,因为我假设有一天它可能会派上用场,因为它们充当了抽象,因此无需我知道就可以更改其实现。
罗布2012年

37
Visual Studio 2015表示应将String.Format更改为string.Format,因此我想Microsoft会采用这种方式。我也一直将String用于静态方法。
Sami Kuhmonen 2014年

32
在阅读完这些内容后,我注意到其中一些评论是完全不正确的。@ DRAirey1及时,您会发现旧方法仍然是最好的,如果您怀疑那我敢于尝试不使用Visual Studio编写C#代码。这几乎是不可能的,Web开发工作中有时会出现这种情况。@Vlad您不需要导入任何内容即可使用String。@Abhi您的评论毫无意义,同样对string.Format()。@KlitosG不,那不是真的。它们的工作原理完全相同。
krowe2

46
您能否添加一句话,说实际上是有区别的?例如:nameof(string)不会编译而nameof(String)将编译。
Jeroen Vannevel'2

3439

为了完整起见,这里有一些相关信息的摘要……

正如其他人指出的那样,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

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

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

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

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

最后,涉及到使用什么:我个人将别名用于实现,但对于任何API均使用CLR类型。在实现方面,您使用哪一个并不重要,因为您的团队之间的一致性很好,但是没有人会在意。另一方面,真正重要的是,如果您在API中引用类型,则必须以与语言无关的方式进行。称为的方法ReadInt32是明确的,而称为的方法ReadInt需要解释。例如,调用者可能使用的语言为定义了int别名Int16。在.NET框架的设计者都遵循这种模式,在很好的例子是BitConverterBinaryReaderConvert类。


82
枚举的继承情况很有趣。您能否指向文档说明为什么必须对别名使用别名?还是这是一个已知的错误?
JaredPar

149
它在规范的14.1节中(因为它太长,我在这里不容易引用)。它没有明确地说,你必须使用别名,但是别名是那种当作自己的类型。有点奇怪。
乔恩·斯基特

32
@PiPeep比大量推荐更令人惊讶的是惊人的低推荐数量(考虑到前5个帖子总共有2000多个推荐,但其中只有1个推荐)。尤其是当您考虑到任何社区中总是存在“仇恨者”的概念时,我真的发现这简直令人难以置信。
corsiKa 2011年

40
string和之间的一个有趣的区别Stringstring' is a keyword in c#, so you can not use it as a variable name.For Ex: 字符串string =“ hi”; //compiler error, but String String =“ hi”;`是可接受的,Stringidentifire不是关键字。
Sanjeev Rai 2013年

33
@SanjeevRai:是的。您可以使用@string创建一个最终看起来像的标识符string。这是一种转义机制。
乔恩·斯基特

715

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

我可以对intSystem.Int32等说同样的话。


3
`如果您使用C#编写代码,我更喜欢string,因为它是C#类型的别名,并且为C#程序员所熟知。我通常认为+1是最好的答案,但我提到的观点似乎很奇怪。
MyDaftQuestions

4
我个人更喜欢使用“ Int32”,因为它会立即显示该值的范围。想象一下,如果他们在更高版本的系统上升级了“ int”的类型。c中的'int'显然被视为“目标处理器最有效使用的整数类型”,并定义为“至少16位”。我希望在那里具有可预测的一致性,非常感谢。
Nyerguds

2
我同意@MyDaftQuestions。如果有任何原因,始终使用.net类型是有意义的,因为它们对语言不了解并且类型很明显,而与任何语言无关(我是否了解F#或VB的所有特质?)。
彼得-恢复莫妮卡的时间

5
@Nyerguds有两个根本不用担心的原因。一个是int在C#语言规范中定义为32位整数,而与硬件无关。尽管在时间的迷雾中有着共同的传统,但C#实际上不是C。更改int为64位整数将是规范和语言的重大变化。它也需要重新定义long,因为long当前是64位整数。不用担心的另一个原因是无关紧要的,因为类型永远不会改变,但是.NET足够抽象,以至于99%的时间您都不必考虑它。;-)
Craig

5
@Craig我掘到很多的旧自主研发的游戏格式,我得想想,所有的时间,虽然。然后使用Int16Int32并且Int64很多的代码比使用相当非描述更加透明shortint并且long
Nyerguds

504

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

  • 我看到许多开发人员感到困惑,他们不知道在他们的代码中使用string还是String。因为在C#中,字符串(关键字)精确地映射到System.String(FCL类型),所以没有区别,并且两者都可以使用。
  • 在C#中,long映射到System.Int64,但是在另一种编程语言中,long可以映射到Int16Int32。实际上,C ++ / CLI实际上确实像Int32一样对待。如果某人阅读一种语言的源代码,如果习惯于使用另一种编程语言进行编程,则很容易会误解该代码的意图。事实上,大多数语言甚至不会把的关键字,将无法编译代码,使用它。
  • 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#世界中陷于困境,但最终还是试图使我的代码看起来像框架代码。


24
第二点实际上听起来像一个理由来使用stringint等等
MauganRa

15
@MauganRa应该是,这本书的作者列出了为什么他不使用别名的那些原因。
tomi.lee.jones

31
“如果有人正在阅读C#源代码,他们应该根据语言规范(而不是其他语言规范)进行长时间解释。” 这完全错了要点。这并不是说任何人都打算误解代码,当一种类型的含义与程序员在另一种情况下每天所看到的含义有所不同时,人的大脑很容易跳到错误的结论。我们都会犯错; 使用显式命名的类型可以减少出现这些错误的可能性。
达里尔

10
这些理由总结了我对此事的看法。当我第一次开始用C#编程(来自Java / C ++ / C背景)时,我认为别名很难看。我仍然有这种感觉,不幸的是,世界上大多数地区似乎并不同意我的观点,或者他们不在乎,因此使用小写字母。
gusgorman

8
@jinzai的问题是关于C#的,而在C#中,它long定义为带符号的64位整数,而不考虑平台或编译器。因此,至少在某些情况下,是的,它的确取决于语言。
phoog

455

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

如果由于某种原因您想要一个名为string的变量,那么您只会看到以下第一个编译:

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

如果您确实想要一个名为string的变量名,则可以将其@用作前缀:

StringBuilder @string = new StringBuilder();

另一个重要的区别:堆栈溢出以不同的方式突出显示它们。


20
请记住,呼叫本地人@string实际上是毫无意义的,因为本地人的名称仅出现在PDB中。最好叫它_string什么。它更有意义的事情上有通过反射,其中一个的名称访问名称@string成员会"string"
罗曼·斯塔科夫

25
还请记住使用保留字,因为变量名非常不雅。
艾尔顿(Elton)2015年

7
OP不想使用String或string作为变量名。他们要求解释这些类型之间的区别。您的回答只会使您更加困惑。IMO
马特·威尔科

1
@craig如果您正在编写软件来教人们如何打结?
Simon_Weaver

5
@Simon_Weaver打结成串吗?哈哈,很好。:-)当然,您可以选择其他名称,例如thread。等一下...天哪!
克雷格

391

有一个区别 -您不能String没有using System;事先使用。


14
默认情况下,大多数人会以任何方式在文件顶部添加此内容。在大多数情况下,VS都会默认执行此操作!
IbrarMumtaz 2010年

9
默认情况下,我仅添加using所需的语句,并明确删除所有不需要的语句。电力生产力工具>“ [x]保存时删除并格式化使用格式”
JMD

2
@JMD我已经修改了.cs模板文件,因此它甚至在顶部甚至没有任何using语句!我还将类模板更改为internal sealed
ErikE '16

@JMD我讨厌这个功能。有时,它会对原本没有修改的文件进行更改,因此很难查看更改集包含的实际更改。当然,我通常会删除“使用垃圾邮件”,但是只会自动删除,不会自动删除。
mg30rg '19

对于C#可能是这样,但并非所有.NET语言。(Powershell默认情况下会导入系统名称空间。)
FSCKur

311

上面已经讲过了;但是,您不能string进行反思;您必须使用String


6
我不明白这个答案的含义,以及为什么它被否决。您可以使用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",则您是对的。
杰普·斯蒂格·尼尔森

256

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

至于指导原则,我不会陷入困境,只要使用您喜欢的任何方式,生活中就会有更重要的事情,而且代码无论如何都将是相同的。

如果你发现自己构建的系统中,需要指定要使用的整数的大小,因此倾向于使用Int16Int32UInt16UInt32等那么它可能看起来更自然的使用String-和不同的.NET语言之间走动时,它可能使事情更容易理解-否则我将使用string和int。


2
只要选择一个并保持一致即可。如果您使用的是房屋风格的地方,请使用它。
艾伦B

3
不幸的是,样式是个人喜好,在没有专用代码所有者的情况下跨多个团队在大型代码库中实施可能太昂贵了。总是比字符串vs字符串更重要的事情要处理。这使我们回到“生活中更重要的事情”
aiodintsov 2016年

这绝对是一种偏爱;例如:我更喜欢使用shortintushortuint而不是Int16等主要是因为这是我的教训。当然,Int16对于经验较少的人来说,更容易立即理解。+1来自我!
艾玛(Emma)

210

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

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

考虑:

String someString; 
string anotherString; 

11
您是否还编写如下代码:Int32 i = 1; 而不是int = 1; ?似乎不一致时不使用字符串别名。
bytedev

29
@nashwan:实际上,是的,我确实使用Int32 i=1;int代替int i = 1; 我发现前者对于我的意图更具可读性:即我想要一个32位有符号整数。
NotMe

5
好吧,我想这全取决于开发人员是否认为他们正在编写C#代码(字符串)或.NET代码(字符串)。我个人最重要的是我在写C#(而使用.NET的是C#)。
bytedev 2014年

7
@Alex:我的意思仅仅是,为了消除歧义,我更喜欢在编码中非常具体。
NotMe

22
在绝对的另一端,我几乎总是使用var
tic

192

string并且String在所有方面都相同(大写字母“ S”除外)。两种方式都不会影响性能。

string由于语法高亮,在大多数项目中首选小写


Jeffrey Richter建议在所有情况下都使用CLR类型(通过C#进行CLR),以避免出现这种情况。
乔什

显然,无论您使用S还是s都会引起此问题,因此请投票否决Richter。;)
Brad Wilson

里希特(Richter)意味着不应该选择字符串-微软不应该使用该语言。您不能拒绝Richter-他是个传奇人物!:)
乔·拉特泽

1
我同意完全不使用别名可能会更好。但是考虑到我们有它们,我认为可以使用它们(但不能在方法名称中使用)
Jon Skeet

10
“字符串”与“字符串”不同。是指“ System.String”。所以,如果你使用“字符串”你必须把“使用系统”包括命名空间
ThiagoAlves

185

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

string 是C#中的类型。

System.String 是CLR中的一种。

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

从理论上讲,您可以实现一个生成Java字节码的C#编译器。为了与Java运行时库互操作,此编译器的明智实现可能会映射stringjava.lang.String


1
string不是C#中的类型;它是一个保留字,它映射到CLR中的类型。
CesarGon

@CesarGon:根据ECMA-334,第8.2.1节:“ C#提供了一组预定义类型[...]预定义引用类型是对象和字符串。”
Rasmus Faber

10
根据ECMA-334,第9.4.3节,“字符串”是一个关键字。:-)如果您关注语义,我同意“字符串”是一种类型,但是如果您关注语法,我会说它是一个关键字(即保留字)。该标准支持这两种观点(可能太含糊了!)。对我来说,OP是关于语法的,所以当我看答案时,我倾向于专注于语法,但是我也明白你的意思。此外,按您的说法,它可能被解释为意味着存在两种不同的类型:string和String,但实际情况并非如此。一个是到另一个的映射。
CesarGon

让我们澄清一下。“字符串”是保留的别名。它不是真正的数据类型。这是指向其他的东西。您可以删除所有这些别名(或者永远不要使用它们),并拥有一种非常好的编程语言。
2013年

168

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

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

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

在此处输入图片说明

System.String”又名“字符串”(大写的“ S”)是.NET框架数据类型,而“字符串”是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

现在从程序员的角度来看百万美元的问题那么,什么时候使用“字符串”和“字符串”呢?

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

在下面的代码中,左侧是变量声明,并且使用“字符串”声明。在右侧,我们正在调用一个方法,因此“字符串”更明智。

string s = String.ToUpper() ;

25
“简而言之,“字符串”是“字符串”的别名(用不同的名称调用的同一事物)”。这是不正确的:别名是“ string”。
Xavier Egea 2014年

3
当您进行变量声明时,最好使用“ string”(小号“ s”),当您将其用作类名时,则首选“ String”(大写“ S”)。该约定似乎不再有效:如果您使用Visual Studio 2015并尝试编写String该建议,则建议您“简化代码”,将其携带到string...
Massimiliano Kraus 2016年

165

小写字母string是的别名System.String。它们在中是相同的C#

有过是否应使用系统类型(辩论System.Int32System.String等)类型或C# aliasesintstring,等)。我个人认为您应该使用C# aliases,但这只是我个人的偏爱。


4
这就是问题所在,它们不是“ C#”别名,而是“ C”别名。C#语言中没有本地的“字符串”或“ int”,只是语法糖。
2015年

16
由于C#5语言规范显示“关键字字符串只是预定义类System.String的别名,”,因此不确定“ C”从何而来。在第85页的第4.2.4段。所有高级语言都是CPU指令集和字节码之上的语法糖。
aiodintsov

156

string只是的别名System.String。编译器将相同地对待它们。

唯一实际的不同是您提到的语法突出显示,using System如果使用则必须编写String


您不需要在System前面加上String。
乔·拉特泽

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


120

正如其他人所说,它们是相同的。了StyleCop规则,默认情况下,将强制你使用string的C#代码风格的最佳实践,引用时除外System.String静态函数,如String.FormatString.JoinString.Concat,等...


4
我不知道StyleCop会标记String的使用-除了静态方法。我认为这很棒,因为这就是我一直使用的方式:用于类型声明的字符串和访问静态成员时的字符串。
Goyuix 2011年

101

6年零5个月后的新答案(精进)。

尽管stringC#保留关键字始终具有固定的含义,但String它只是可以引用任何内容的普通标识符。根据当前类型的成员,当前名称空间和所应用的using指令及其位置String可以是一个值或一个不同于的类型global::System.String

我将提供两个示例,其中using指令无济于事


首先,when 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)(可能会取决于usings)使用Linq扩展方法Enumerable.Concat。它不会转到静态方法string.Concat


其次,when String是另一个类型,嵌套在当前类型内:

class MyPiano
{
  protected class String
  {
  }

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

Example方法中的任何一条语句都不会编译。这String始终是一个钢琴MyPiano.String。(static或没有)成员不Format存在(或从其基类继承)。该值"Goodbye"不能转换为它。


4
我想可能是个恶魔般的人:using String = System.Int32; using Int32 = System.String; 然后算出错误。
史蒂夫

7
这是正确的答案。stringSystem.StringString可以是任何东西。
戴夫·库西诺

同意@DaveCousineau-这就是别名的意义。您可以创建另一个String不会设置为System.String对象的类型。退房:blog.paranoidcoding.com/2019/04/08/...
Kristopher

“关键字string在C#中具有具体含义。它是System.String核心运行时程序集中存在的类型。运行时从本质上理解此类型并提供开发人员strings在.NET中期望的功能。它的存在对于C#至关重要,因此如果该类型不起作用,不存在,编译器将在尝试甚至解析一行代码之前退出。因此string,在C#代码中具有精确,明确的含义。String尽管在C#中标识符没有具体含义,但它是通过所有名称查找规则的标识符如WidgetStudent等...”
Kristopher



87

反对什么似乎其他程序员是常有的事,我更喜欢Stringstring,只是为了强调一个事实,即String是引用类型,如乔恩斯基特提及。



78

我只想在Ritchers的书中将其添加到lfousts答案中:

C#语言规范指出:“就样式而言,使用关键字胜于使用完整的系统类型名称。” 我不同意语言规范;我更喜欢使用FCL类型名称,而完全避免使用原始类型名称。实际上,我希望编译器甚至不提供原始类型名称,而强迫开发人员改用FCL类型名称。这是我的原因:

  • 我看到许多开发人员感到困惑,他们不知道在他们的代码中使用string 还是String。因为在C#中,字符串(关键字)完全映射到 System.String(FCL类型),所以没有区别,并且两者都可以使用。同样,我听过一些开发人员说,当应用程序在32位操作系统上运行时,int表示一个32位整数,而当应用程序在64位操作系统上运行时,它表示一个64位整数。该语句绝对是错误的:在C#中,int始终映射到System.Int32,因此,无论代码运行在哪个OS上,它都表示一个32位整数。如果程序员会使用在其代码int32中,那么这种潜在的混乱也被消除了。

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

  • 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#原理潜入了类库代码中。例如,Microsoft的FCL几乎完全是用C#编写的,并且FCL团队的开发人员现在已将方法引入到库中,例如 ArrayGetLongLength,该方法返回的Int64值在C#中很长,但在其他语言(例如C ++)中却不是/ CLI)。另一个示例是System.Linq.EnumerableLongCount方法。

在阅读全文之前,我没有听他的意见。


72

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


67

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


67

确实,这是惯例问题。 string看起来更像C / C ++风格。一般约定是使用您选择的语言提供的任何快捷方式(in / Int为Int32)。这也适用于“对象” decimal

从理论上讲,这可以帮助将代码移植到将来的某些64位标准中,其中“ int”可能意味着Int64,但这不是重点,我希望任何升级向导都可以将任何int引用更改Int32为安全。


66

迟到了:我100%的时间都使用CLR类型(嗯,除非被迫使用C#类型,但我不记得上一次是什么时候)。

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

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

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

而且,现在,当我看到“ int”或“ string”时,对我来说真的很不对劲,就像我在看1970年代的C代码一样。


49

没有区别。

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

同样,int映射到System.Int32


在64位版本中,int映射到System.Int64(8字节),在32位版本中,它映射到System.Int32(4字节)
Alex

1
IntPtr和UIntPtr是根据平台更改大小的唯一类型(忽略诸如[U] IntPtrs或实际指针组成的实际指针类型int*和类型)。
P Daddy

45

丹尼尔·索利斯(Daniel Solis)的书中有一个关于这个问题的报价。

所有预定义的类型都直接映射到基础.NET类型。C#类型名称(字符串)只是.NET类型(字符串或System.String)的别名,因此尽管不建议使用.NET名称,但在语法上可以正常使用。在C#程序中,应使用C#名称而不是.NET名称。


41

string是一个关键字,您不能使用string作为标识符。

字符串不是关键字,您可以将其用作标识符:

string String = "I am a string";

关键字stringSystem.String除了关键字issue之外的别名 ,两者完全相同。

 typeof(string) == typeof(String) == typeof(System.String)

2
唯一的微小区别是,如果使用String类,则需要在文件顶部导入System名称空间,而在使用string关键字时则不必这样做。
乌塔姆'18

在简单的用例中,相等性语句将失败...例如在blah名称空间中定义类型调用String并将该名称空间导入到运行相等性语句的文件中。
里克

40

是的,它们之间没有区别,就像bool和一样Boolean


40

@JaredPar(C#编译器的开发者和多产的SO用户!)就此问题撰写了一篇很棒的博客文章。我认为值得在这里分享。这是关于我们主题的一个很好的观点。

stringvs. String不是一场风格辩论

[...]

关键字string在C#中具有具体含义。它是System.String核心运行时程序集中存在的类型。运行时从本质上理解这种类型,并提供了开发人员期望的.NET字符串功能。它的存在对C#至关重要,如果不存在该类型,编译器将在尝试解析一行代码之前退出。因此string在C#代码中具有精确,明确的含义。

标识符String虽然在C#中没有具体含义。它是一个经过所有名称查找规则的标识符,例如WidgetStudent等等。它可以绑定到字符串,也可以绑定到另一个程序集中的某个类型,其目的可能与完全不同string。更糟糕的是,它的定义方式可能像这样的代码String s = "hello";继续编译。

class TricksterString { 
  void Example() {
    String s = "Hello World"; // Okay but probably not what you expect.
  }
}

class String {
  public static implicit operator String(string s) => null;
}

的实际含义String将始终取决于名称解析。这意味着它取决于项目中的所有源文件以及所有引用的程序集中定义的所有类型。简而言之,要了解它的含义需要相当多的上下文。

确实,在绝大多数情况下Stringstring它将绑定到相同类型。但是使用String仍然意味着开发人员只能在只有一个正确答案的地方让程序自行解释。当String确实绑定到错误的类型时,它可能会使开发人员进行数小时的调试,将错误提交给编译器团队,并且通常会浪费时间,而这可以通过使用节省string

可视化差异的另一种方法是使用以下示例:

string s1 = 42; // Errors 100% of the time  
String s2 = 42; // Might error, might not, depends on the code

许多人会争辩说,尽管这是技术上准确的信息,但String仍然可以使用,因为很少有代码库会定义此名称的类型。或者,当String定义它时,就表明代码库不正确。

[...]

你会看到,String被定义为一些完全有效的用途:反射帮手,系列化库,词法分析器,协议等...对于任何的这些库Stringstring具有真正的影响取决于在代码中使用。

因此,请记住,当您看到Stringvs. string辩论时,这是关于语义而不是样式的。选择字符串可使代码库具有清晰的含义。选择String并没有错,但它为将来的惊喜打开了大门。

注意:出于存档原因,我复制/粘贴了大多数博客文章。我忽略了某些部分,因此建议您跳过并阅读博客文章

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.