C#中字符串和字符串有什么区别?
示例(注意案例):
string s = "Hello world!";
String s = "Hello world!";
每种使用的准则是什么?有什么区别?
回答
string
是C#中的别名System.String
.
从技术上讲,没有区别.这就像int
对战 System.Int32
.
就指南而言,通常建议string
您在引用对象时使用.
例如
string place = "world";
同样,我认为String
如果您需要专门参考该课程,通常建议使用它.
例如
string greet = String.Format("Hello {0}!", place);
这是Microsoft在其示例中倾向于使用的样式.
看来这个领域的指导可能已经改变,因为StyleCop现在强制使用C#特定的别名.
- 如果你决定使用StyleCop并遵循它,那就说要使用特定于该语言的类型.所以对于C#,你将拥有字符串(而不是String),int(而不是Int32),float(而不是Single) - http://stylecop.soyuz5.com/SA1121.html
- 我总是使用别名,因为我假设有一天它可能会派上用场,因为它们充当抽象,因此可以在不必我知道的情况下改变它们的实现.
- 您能否添加一条评论,实际上存在差异?例如:`nameof(string)`将不会编译,而`nameof(String)`将会编译.
- Visual Studio 2015说String.Format应该改为string.Format,所以我猜微软就是这样.我也一直使用String作为静态方法.
- 正如我读过这些,我注意到有几条评论是不正确的.@ DRAirey1随着时间的推移,您会发现旧的方式仍然是最好的,如果您怀疑那么我敢于尝试在不使用Visual Studio的情况下编写C#代码.这实际上是不可能的,并且在Web开发工作中不时出现这种情况.@Vlad你不需要导入任何东西来使用String.@Abhi你的评论毫无意义,同样适用于`string.Format()`.@KlitosG不,那不是真的.它们都完全一样.
- 关键区别是`string`保证总是引用`System.String`,而`String`可以引用不同命名空间中具有相同名称的不同类
- 抱歉这个愚蠢的问题,但是为什么我们需要这样的别名?
- @Dominic:虽然是成员名,但不是实施.我很喜欢(比方说)public int ReadInt32().
- @JonSkeet - 和你一样,我更喜欢别名类型.[开发类库的设计指南 - 一般命名约定](http://msdn.microsoft.com/en-us/library/ms229045.aspx)建议开发人员坚持使用特定于语言的命名,而不是CLR类型.他们在`Convert`方法中这样做,以保存它们为每种语言重新定义它.
- 不是第二个例子"`string greet = String.Format("Hello {0}!",place);" 意味着有一个资本S?串?
- 我不喜欢别名.类名感觉合理使用(例如String.Format()),通常更具描述性(例如Int32 vs int),并且在它适合框架(在System中)的位置立即清楚.但看起来MS希望我们使用别名,这就是我们必须要做的事情.
- Visual Studio 2015建议使用string.Format
- 我以前更喜欢语法`String.Format()`,但最新版本的Visual Studio实际上将其标记为可以简化的表达式.当你简化它时,它就变成了`string.Format()`.因此,就Visual Studio而言,使用C#时,`string`始终是*首选语法.
- @SparK不,`string`不是结构; 它总是指System.String类.它们在IL中是100%相同的.
- 我在实际源代码中实际看到的String.Format的一个主要优点是当它以这种方式使用时,String.Format("a的值为{0}",a); a是声明和初始化的任何变量.这种格式化字符串的方式具有各种优点.一个非常简单的例子是,当变量a是货币的值时,我们可以使用£或$或格式化为字符串的任何货币符号.
- Java需要这些别名,当我使用“字符串”而不是“字符串”时会很生气。C#不在乎。
- 所以这里的每个人都建议这样做?`new string('-',100)` 当访问诸如Int32.Parse之类的静态成员或调用构造函数时,我更喜欢使用BCL名称。指定类型时,请使用别名。
只是为了完整起见,这里是相关信息的大脑转储......
正如其他人所说,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
这只是一个的规范定义枚举声明的方式事情-冒号后的部分必须是整体式的生产,这是一个标志sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
...,而不是一个类型生产为例如,由变量声明使用.它并不表示任何其他差异.
最后,当涉及到使用哪个时:我个人在各处使用别名来实现,但是任何API都使用CLR类型.你在实施方面使用它并不重要 - 团队之间的一致性很好,但没有人会关心.另一方面,如果您在API中引用类型,则以语言中立的方式执行此操作,这一点非常重要.调用的方法ReadInt32
是明确的,而调用的方法ReadInt
需要解释.例如,调用者可能正在使用定义int
别名的语言Int16
.在.NET框架的设计者都遵循这种模式,在很好的例子是BitConverter
,BinaryReader
和Convert
类.
- 这是在规范的第14.1节(我不能轻易引用,因为它太长了).它没有明确说明你必须使用别名,但别名是*被视为自己的类型.这有点奇怪.
- 枚举的继承情况很有趣.您是否可以指出为什么必须使用别名进行枚举的文档?或者这是一个已知的错误?
- `string`和`String`之间的一个有趣的区别是`string'是c#中的关键字,所以你不能将它用作变量名.例如:`string string ="hi";`//编译错误,但是`String String ="hi";`是可以接受的,因为`String`是一个标识而不是关键字.
- @SanjeevRai:是的.您可以使用`@ string`创建一个最终为`string`的标识符.这是一种逃避机制.
- @PiPeep比大量的投票更令人震惊的是惊人的低数量的downvotes(考虑前5个帖子总共超过2000个upvotes,但其中只有1个downvote全部).特别是当你考虑到任何社区中总是存在"仇恨"的概念时,我真的觉得这简直令人难以置信.
- @PeterPorfy`System.Void`在检查没有返回值的方法时用于反射,例如在[`MethodInfo.ReturnParameter`]中(http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo) .returntype.aspx).
- @pinusnegra:不,它不是 - 至少与其他人不一样.例如,您不能将方法声明为返回`System.Void`.你不能直接在C#中使用`System.Void`.
- @JonSkeet啊,对吧:)我没有检查,只是想知道,因为我认为这是一个关键字.那么System.Void有什么意义呢?
- 感谢@JonSkeet的精彩解释!在一个较轻松的说明中,几年前我有一位同事喜欢使用System.String,因为他喜欢视觉工作室提供的浅绿色,而不是深蓝色的"字符串"!
- 你的评论:"它没有明确表示你必须使用别名,但别名被视为他们自己的类型.这有点奇怪."
- "别名都是值类型"对于不同的别名集说了两次.两次都不可能是真的%)
- @HusseinX:当然 - 查看CLI规范,你会发现没有处理`decimal`的指令.就CLR而言,它只是"另一种价值类型".
- @phoog:啊,对不起,我没有意识到你指的是评论.是的,这是明确的,我同意.
- 当您对字符串或字符串执行f12时,它将转到相同的String类元数据文件.
- @NielsKeurentjes通过了解F#的单位类型,我更接近虚空的概念.反思也很有道理,谢谢!
- @JonSkeet看起来`enum`s-must-use-alias要求已在C#6或之前的某个时间解除([相关问题](http://stackoverflow.com/q/37589056/335858)) .
- @SparK:不,完全没有.枚举也不是围绕类的包装器.`uint`只是`UInt32`的别名.它们是完全相同的类型,两种结构(不是类).
String
代表System.String
它,它是.NET Framework类型.string
是 C#语言中 的别名System.String
.它们都编译成System.String
IL(中间语言),所以没有区别.选择你喜欢的并使用它.如果您使用C#编写代码,我更喜欢string
它,因为它是C#类型的别名,并且是C#程序员所熟知的.
我可以对(int
,System.Int32
)等说同样的话.
- 我个人更喜欢使用“ Int32”,因为它会立即显示该值的范围。想象一下,如果他们在更高版本的系统上升级了“ int”的类型。c中的“ int”显然被视为_“目标处理器最有效使用的整数类型” _,并定义为“至少16位”。我希望在那里具有可预测的一致性,非常感谢。
- @Craig我深入研究了许多旧的专有游戏格式,但我不得不一直考虑这个问题.然后使用`Int16`,`Int32`和`Int64`在代码中比使用相当无描述的`short`,`int`和`long`更透明_lot
- `如果用C#编写代码,我更喜欢字符串,因为它是C#类型的别名,而且是C#程序员所熟知的 - 当C#人不知道.NET框架时.我认为+1是最好的答案,但我提到的这一点似乎很奇怪.
- @Nyerguds有两个理由不必担心它.一种是,无论硬件如何,`int`在C#语言规范中定义为32位整数.C#,尽管在时间的迷雾中有共同的遗产,但实际上并不是C.将`int`更改为64位整数将是规范和语言的重大变化.它还需要重新定义`long`,因为`long`目前是64位整数.不用担心的另一个原因是不相关的,因为类型永远不会改变,但.NET只是抽象的,99%的时候你不必考虑它.;-)
- But short, not, long, float, double, et al *are* descriptive, because they’re in the language spec. C# is not C. I prefer them on declarations because they’re concise, small, and aesthetically pleasing. I do prefer the Torre library names on API’s where the API has a data type dependency.
- 我同意@MyDaftQuestions。如果有什么用,因为始终不懂任何语言,所以*一致地使用.net类型*是有意义的,因为它们是不懂语言的,并且类型明显,与任何语言无关(我知道F#或VB的所有特质吗?)。
我听说过在C#中使用提供的类型别名的最佳答案来自Jeffrey Richter在他的书" CLR Via C#"中.以下是他的3个理由:
- 我看到许多开发人员感到困惑,不知道是否在他们的代码中使用字符串或字符串.因为在C#中,字符串(关键字)完全映射到System.String(一种FCL类型),所以没有区别,任何一种都可以使用.
- 在C#中,长映射到System.Int64,但是在不同的编程语言中,long可以映射到Int16或Int32.事实上,C++/CLI确实将long视为Int32.如果某人使用一种语言阅读源代码,如果他或她习惯于使用不同的编程语言进行编程,则很容易误解代码的意图.实际上,大多数语言甚至不会将long视为关键字,也不会编译使用它的代码.
- FCL有许多方法,它们将类型名称作为其方法名称的一部分.例如,BinaryReader类型提供诸如ReadBoolean,ReadInt32,ReadSingle等方法,而System.Convert类型提供诸如ToBoolean,ToInt32,ToSingle等方法.虽然编写下面的代码是合法的,但浮点线对我来说感觉非常不自然,并且线条不正确并不明显:
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good
所以你有它.我认为这些都是非常好的观点.但是,我发现自己在自己的代码中没有使用Jeffrey的建议.也许我太困在我的C#世界,但我最终试图使我的代码看起来像框架代码.
- "如果有人正在阅读C#源代码,他们应该根据语言规范解释很久,而不是其他语言规范." 这完全忽略了这一点.并不是任何人都会误解代码,当一个类型具有与程序员在另一个环境中每天看到的不同的含义时,一个人的大脑很容易跳到错误的结论.我们都会犯错; 使用明确命名的类型使这些错误的可能性降低.
- 第二点听起来实际上是一个原因*不*使用`string`,`int`等.
- @MauganRa本应该如此,这本书的作者列出了他为什么不使用别名的原因.
- +这些原因总结了我对此事的感受.当我第一次开始用C#编写代码(来自Java/C++/C背景)时,我认为别名很难看.我仍然有这种感觉,不幸的是,世界上大多数人似乎都不同意我,或者他们并不关心,所以使用小写字母.
- @jinzai的问题是关于C#,其中`long`被定义为带符号的64位整数,无论平台还是编译器.所以在某些情况下,至少,是的,它*取决于语言.
- @Darryl - 我记得在Windows XP 32x上用.NET 1.x编程.其中一个内核API需要一个`long`,并且我通过使用.NET long来传递溢出错误; 它必须是.NET int/Int32才能转换为内核对`long`的定义.所以仍有混淆的余地!https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
- 整数的"bittedness"依赖于编译器,而不是语言.你使用"long"溢出的原因不是因为内核,而是因为编译器.Microsoft 16位编译器使用16位整数,32位编译器使用32位整数."string":实际上是char*的"别名",但这完全是.NET的窗口 - 这就是为什么IntPtr没有原始等价物 - 没有指针.
- 我发现的最好的书是CLR通过C#...`
string
是一个保留字,但String
只是一个类名.这意味着它string
本身不能用作变量名.
如果由于某种原因你想要一个名为string的变量,你只能看到第一个这样的编译:
StringBuilder String = new StringBuilder(); // compiles
StringBuilder string = new StringBuilder(); // doesn't compile
如果你真的想要一个名为string的变量名,你可以@
用作前缀:
StringBuilder @string = new StringBuilder();
另一个重要区别:Stack Overflow以不同的方式强调它们.
- 另外请记住使用保留字作为变量名称是非常不优雅的.
- 请记住,调用本地`@ string`实际上是毫无意义的,因为本地的名称只存在于PDB中.不妨称它为`_string`或者其他东西.对于具有可通过反射访问的名称的东西更有意义,其中`@ string`成员的名称将是`"string"`.
- OP不希望使用String或string作为变量名.他们要求解释这些*类型*之间的区别.你的回答只会增加IMO的混乱
- @Simon_Weaver打结成串吗?哈哈,很好。:-)当然,您可以选择其他名称,例如thread。等一下...天哪!
有一个区别 -你不能使用String
没有using System;
事先.
- 默认情况下,大多数人会以任何方式在文件顶部添加此项.默认情况下,VS会在大多数情况下执行此操作!
- 默认情况下,我只添加我需要的`using`语句,并明确删除所有我不需要的语句.Power Productivity Tools>"[x]删除并格式化保存时的使用"
- @JMD我修改了.cs模板文件,所以它甚至没有顶部的任何using语句!我还将类模板更改为`internal sealed`.
它已被覆盖; 但是,你不能用于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””进行比较,那是正确的。
System.String
是.NET字符串类 - 在C#中string
是别名System.String
- 所以在使用它们是相同的.
至于指导方针,我不会陷入困境,只是使用你想要的任何东西 - 生活中有更重要的事情,无论如何代码都是一样的.
如果你发现自己构建的系统中,需要指定要使用的整数的大小,因此倾向于使用Int16
,Int32
,UInt16
,UInt32
等那么它可能看起来更自然的使用String
-和不同的.NET语言之间来回移动时,它可能让事情更容易理解 - 否则我会使用string和int.
- 不幸的是,样式是个人偏好,并且可能太昂贵,无法在没有专用代码所有者的情况下在多个团队的大型代码库中强制执行.总是有更重要的事情要照顾而不是字符串vs String.这让我们回到"生活中更重要的事情"
.NET
出于格式化原因,
我更喜欢大写类型(而不是别名).的.NET
类型是彩色一样其他对象类型(该值的类型是正确的对象,毕竟).
条件和控制关键字(如if
,, switch
和return
)是小写的,并且是深蓝色(默认情况下).我宁愿在使用和格式方面没有分歧.
考虑:
String someString;
string anotherString;
- @nashwan:实际上,是的,我确实使用`Int32 i = 1;`而不是`int i = 1;`我发现前者对我的意图更具可读性:即我想要一个32位有符号整数.
- 在频谱的绝对另一端,我几乎总是只使用`var`
- 你也写代码如下:Int32 i = 1; 而不是int i = 1; ?似乎不一致,当它可用时不使用字符串别名.
- @Alex:我的观点是,我更喜欢在编码中非常具体,以消除歧义.
- 嗯,我想这完全取决于开发人员是否认为他们正在编写C#代码(字符串)或.NET代码(String).我个人认为我正在编写C#(而且它是使用.NET的C#).
string
并且String
在所有方面都是相同的(除了大写的"S").无论如何都没有性能影响.
string
由于语法高亮,大多数项目都首选小写
- "string"与"String"不同.是指"System.String".因此,如果使用"String",则必须使用"using System"来包含命名空间
C#是一种与CLR一起使用的语言.
string
是C#中的一个类型.
System.String
是CLR中的一种类型.
当您将C#与CLR一起使用时,string
将映射到System.String
.
从理论上讲,您可以实现生成Java字节码的C#编译器.这个编译器的合理实现可能会映射string
到java.lang.String
以便与Java运行时库进行互操作.
- 根据ECMA-334第9.4.3节,"string"是一个关键字.:-)我同意你的看法,如果你专注于语义,"string"是一种类型,但如果你专注于语法,我会说它是一个关键字(即一个保留字).该标准支持两种观点(可能过于含糊不清!).对我来说,OP是关于语法的,所以当我查看答案时,我倾向于关注语法,但我也看到了你的观点.此外,您的答案可能被解释为意味着存在两种不同的类型:字符串和字符串,而不是这种情况.一个是对另一个的maping.
此YouTube视频实际上展示了它们的不同之处.
但现在需要长篇文章答案.
当我们谈论.NET
有两个不同的东西一个有.NET
框架和其他有语言(C#
,VB.NET
等等),它使用的框架.
" System.String
"aka"String"(大写"S")是.NET
框架数据类型,而"string"是C#
数据类型.
简而言之,"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 s = String.ToUpper() ;
- "简而言之,"字符串"是"字符串"的别名(用不同的名称命名).这是不正确的:别名是"string".
- _when你做变量声明这是很好用"串"(小的"S"),当你使用它作为一个类名,然后"字符串"(大写字母"S")是preferred._该公约似乎没有更有效:如果您使用Visual Studio 2015并尝试编写`String`,它建议您"简化您的代码",将其带到`string` ...
小写string
是别名System.String
.它们是相同的C#
.
有过是否应使用系统类型(辩论System.Int32
,System.String
等)类型或C# aliases
(int
,string
,等).我个人认为你应该使用C# aliases
,但这只是我个人的偏好.
- 不确定"C"来自何处,因为C#5语言规范读取"关键字字符串只是预定义类System.String的别名".在第85页,第4.2.4段.所有高级语言都是CPU指令集和字节码的语法糖.
- 这就是问题,它们不是'C#'别名,它们是'C'别名.C#语言中没有原生的'string'或'int',只是语法糖.
string
只是一个别名System.String
.编译器会以相同的方式处理它们.
唯一的实际区别是你提到的语法高亮,using System
如果你使用你必须写String
.
- 使用`String`时,你必须包含一个`using System`,否则会出现以下错误:`找不到类型或命名空间名称'String'(你是否缺少using指令或程序集引用?)
两者都是一样的.但从编码指南的角度来看,最好使用string
而不是String
.这是开发人员通常使用的.例如,而不是使用Int32
我们使用int
as int
asiasInt32
仅供参考"关键字字符串只是预定义类的别名System.String
." - C#语言规范4.2.3
http://msdn2.microsoft.com/En-US/library/aa691153.aspx
正如其他人所说,他们是一样的.了StyleCop规则,默认情况下,将强制你使用string
的C#代码风格的最佳实践,引用时除外System.String
静态函数,如String.Format
,String.Join
,String.Concat
,等...
- 我不知道StyleCop会标记字符串使用 - 除了静态方法.我认为这很好,因为我总是使用它:类型声明的字符串和访问静态成员时的字符串.
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!";
可以是OK(取决于命名空间和using
指令).
更糟糕的是:说String.Concat(someSequence)
可能(取决于using
s)转到Linq扩展方法Enumerable.Concat
.它不会转到静态方法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
.不存在任何成员(static
或不Format
存在)(或从其基类继承).而且价值"Goodbye"
无法转化为它.
- 这是正确的答案。字符串是System.String。`String`可以是任何东西。
- 我想是恶魔般的:`using String = System.Int32; 使用Int32 = System.String;`然后计算错误.
- 在Meta上使用的磁盘:https://meta.stackoverflow.com/questions/385304/highly-upvoted-incorrect-answers-on-questions-are-harmful?cb = 1
使用系统类型可以更容易地在C#和VB.Net之间进行移植,如果你是这样的话.
反对什么似乎其他程序员是常有的事,我更喜欢String
过string
,只是为了强调一个事实,即String
是引用类型,如乔恩斯基特提及.
string
是别名(或简写)System.String
.这意味着,通过键入string
我们的意思System.String
.您可以在思考链接中阅读更多内容:'string'是System.String的别名/简写.
我想将此添加到来自Ritchers书中的lfousts答案中:
BinaryReader br = new BinaryReader(...); float val = br.ReadSingle(); // OK, but feels unnatural Single val = br.ReadSingle(); // OK and feels good
在我阅读完整段落之前,我没有得到他的意见.
String(System.String
)是基类库中的一个类.string(小写)是C#中的保留工作,它是System.String的别名.Int32 vs int是一个类似的情况Boolean vs. bool
.这些特定于C#语言的关键字使您能够以类似于C的样式声明基元.
String
不是关键字,它可以用作标识符,string
而是关键字,不能用作标识符.并且在功能上看两者都是一样的.
聚会迟到:我100%使用CLR类型(好吧,除非被迫使用C#类型,但我不记得最后一次是什么时候).
根据Ritchie的CLR书籍,我最初几年前开始做这件事.我认为所有CLR语言最终都必须能够支持CLR类型集,因此使用CLR类型本身提供了更清晰,可能更"可重用"的代码.
现在我已经做了多年,这是一种习惯,我喜欢VS为CLR类型显示的颜色.
唯一真正的下载是自动完成使用C#类型,所以我最终重新键入自动生成的类型来指定CLR类型.
而且,现在,当我看到"int"或"string"时,我看起来真的很不对劲,就像我在看1970年代的C代码一样.
真的,这是一个惯例问题. string
看起来更像是C/C++风格.一般约定是使用您选择的语言提供的任何快捷方式(int/Int for Int32
).这也适用于"对象" decimal
.
从理论上讲,这可能有助于将代码移植到未来的64位标准中,其中"int"可能意味着Int64
,但这不是重点,我希望任何升级向导都可以更改任何int
引用,Int32
只是为了安全.
没有区别.
C#关键字string
映射到.NET类型System.String
- 它是一个保持语言命名约定的别名.
同样,int
映射到System.Int32
.
Daniel Solis的书中引用了这个问题.
string是关键字,您不能使用string作为标识符.
String不是关键字,您可以将其用作标识符:
例
string String = "I am a string";
除关键字问题外,关键字string
是别名
System.String
,两者完全等效.
typeof(string) == typeof(String) == typeof(System.String)
- 唯一的微小区别是,如果使用String类,则需要在文件顶部导入System名称空间,而在使用string关键字时不必这样做。
是的,他们之间没有区别,就像bool
和Boolean
.
两者之间没有区别 - string
但是,在考虑其他开发人员的源代码时,它似乎是首选方案.
在其他地方没有提到的一个论点更喜欢pascal案例String
:
System.String
是一种引用类型,引用类型名称按惯例为pascal.
- 套接字约定在引用类型和值类型之间没有区别,正如您自己提到的`Int32`类型所证明的那样.避开关键字以支持类名是没有意义的,以遵守一些想象的限制,即引用类型遵循不同的命名约定而不是值类型.
- -1按惯例,所有类型名称都是pascal case.但C#关键字都是小写的.
@JaredPar(C#编译器的开发者和多产的SO用户!)就此问题撰写了一篇很棒的博客文章。我认为值得在这里分享。这是关于我们主题的一个很好的观点。
string
vs.String
不是一场风格辩论[...]
关键字
string
在C#中具有具体含义。它是System.String
核心运行时程序集中存在的类型。运行时从本质上理解这种类型,并提供了开发人员期望的.NET字符串功能。它的存在对C#至关重要,如果不存在该类型,编译器将在尝试解析一行代码之前退出。因此string
在C#代码中具有精确,明确的含义。标识符
String
虽然在C#中没有具体含义。它是通过所有的名字查找规则推移的标识符Widget
,Student
等...它可以结合串或者它可以结合到一个类型在另一组件完全其目的可以比完全不同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
将始终取决于名称解析。这意味着它取决于项目中的所有源文件以及所有引用的程序集中定义的所有类型。简而言之,要了解它的含义需要相当多的上下文。确实,在绝大多数情况下
String
,string
它将绑定到相同类型。但是使用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
被定义为一些完全有效的用途:反射帮手,系列化库,词法分析器,协议等...对于任何的这些库String
与string
具有真正的影响取决于在代码中使用。因此,请记住,当您看到
String
vs.string
辩论时,这是关于语义而不是样式的。选择字符串可使代码库具有清晰的含义。选择String
并没有错,但它为将来的惊喜打开了大门。
注意:出于存档原因,我复制/粘贴了大多数博客文章。我忽略了某些部分,因此建议您跳过并阅读博客文章。
两者都是一样的.区别在于你如何使用它.公约是,
s tring是变量
S tring用于调用其他String类方法
喜欢:
string fName = "John";
string lName = "Smith";
string fullName = String.Concat(fName,lName);
if (String.IsNullOrEmpty(fName))
{
Console.WriteLine("Enter first name");
}
- 这个约定不再有效:如果你使用Visual Studio 2015并尝试使用`String`,程序会建议你"简化代码",将它带到`string`.
实际上没有区别
C#关键字字符串映射到.NET类型System.String - 它是一个保持语言命名约定的别名.
string
和之间有一个实际的区别String
.
nameof(String); // compiles
nameof(string); // doesn't compile
这是因为string
是关键字(在这种情况下是别名),String
而是一种类型.
其他别名也是如此.
| Alias | Type |
|-----------|------------------|
| bool | System.Boolean |
| byte | System.Byte |
| sbyte | System.SByte |
| char | System.Char |
| decimal | System.Decimal |
| double | System.Double |
| float | System.Single |
| int | System.Int32 |
| uint | System.UInt32 |
| long | System.Int64 |
| ulong | System.UInt64 |
| object | System.Object |
| short | System.Int16 |
| ushort | System.UInt16 |
| string | System.String |
如果确实看到string
和之间没有区别是有用的System.String
:
var method1 = typeof(MyClass).GetMethod("TestString1").GetMethodBody().GetILAsByteArray();
var method2 = typeof(MyClass).GetMethod("TestString2").GetMethodBody().GetILAsByteArray();
//...
public string TestString1()
{
string str = "Hello World!";
return str;
}
public string TestString2()
{
String str = "Hello World!";
return str;
}
两者都产生完全相同的IL字节数组:
[ 0, 114, 107, 0, 0, 112, 10, 6, 11, 43, 0, 7, 42 ]
- 我已经给你+1了,但你的实际方法,当优化+打开时,同样是"返回"Hello World!";`.要实际确保类型被"考虑",你可以使用`return(string)(object)typeof(string).Name;`和`return(System.String)(System.Object)typeof(System.String).Name; `,恰好确认`System.Object`也与`object`相同:-)
String
指的是一个字符串对象,它带有各种用于操作包含的字符串的函数.
string
指原始类型
在C#中,它们都编译为String,但在其他语言中它们不是,因此如果要处理String对象,则应使用String,如果要处理文字,则应使用字符串.
您不需要使用import namespace(using System
;),string
因为它是全局别名System.String
.
要了解有关别名的更多信息,请查看此链接.
首先,两者(字符串和字符串)不相同.区别是:String不是关键字,可以用作标识符,而string是关键字,不能用作标识符.
我试图用不同的例子来解释:首先,当我把"string s"时 进入Visual Studio并将鼠标悬停在它上面(没有颜色):
那说字符串是System.String,对吧?该文档位于https://msdn.microsoft.com/en-us/library/362314fe.aspx.第二句话说"string是.NET Framework中String的别名".
- 所以内心他们是一样的.意思是,它们指向同一个东西,并且可以互换使用.它们的区别在于String是定义的实际结构的名称,而string是指向同一结构的别名.它(字符串)是一个别名使它成为一个关键字,这就是VS将它们显示为差异颜色的原因.如果右键单击以查看字符串的定义,您将盯着struct String.
杰弗里里希特写道:
using int = System.Int32;
using uint = System.UInt32;
using string = System.String;
...
String: String对象称为immutable(只读),因为一旦创建了它就无法修改它的值.看似修改String对象的方法实际上返回一个包含修改的新String对象.如果有必要修改类似字符串的对象的实际内容
string:字符串类型表示零个或多个Unicode字符的序列.string是.NET Framework中String的别名.string
是内在的C#数据类型,是系统提供的类型"System.String"的别名.C#规范声明,作为一种样式,关键字(字符串)优先于整个系统类型名称(System.String或String).虽然string是引用类型,但是定义了相等运算符(==和!=)来比较字符串对象的值,而不是引用.这使得对字符串相等性的测试更加直观.例如:
string&String之间的区别:
- 在
string
通常用于声明同时String
用于访问静态字符串的方法 - 你可以使用
'string'
do声明字段,使用预定义类型的属性等'string'
,因为C#规范告诉我这是好的样式. - 您可以使用
'String'
系统定义的方法,例如String.Compare等.它们最初在'System.String'上定义,而不是'string'.'string'
在这种情况下只是一个别名. -
'String'
在与其他系统通信时,您也可以使用或"System.Int32",特别是如果它们符合CLR.即 - 如果我从其他地方获取数据,我会将其反序列化为System.Int32而不是'int',如果定义的原点不是C#系统.
说实话,在实践中,System.String和string之间通常没有区别.
C#中的所有类型都是对象,所有类型都派生自System.Object类.一个区别是string是一个C#关键字,String可以用作变量名.System.String是这种类型的传统.NET名称,字符串是方便的C#名称.这是一个简单的程序,它显示了System.String和string 之间的区别.
string a = new string(new char[] { 'x', 'y', 'z' });
string b = new String(new char[] { 'x', 'y', 'z' });
String c = new string(new char[] { 'x', 'y', 'z' });
String d = new String(new char[] { 'x', 'y', 'z' });
MessageBox.Show((a.GetType() == typeof(String) && a.GetType() == typeof(string)).ToString()); // shows true
MessageBox.Show((b.GetType() == typeof(String) && b.GetType() == typeof(string)).ToString()); // shows true
MessageBox.Show((c.GetType() == typeof(String) && c.GetType() == typeof(string)).ToString()); // shows true
MessageBox.Show((d.GetType() == typeof(String) && d.GetType() == typeof(string)).ToString()); // shows true
@JonSkeet在我的编译器中
public enum Foo : UInt32 { }
工作中.我是Visual Studio 2015社区.
在的上下文MSDN文档,String
类是记录像任何其它数据类型(例如,XmlReader
,StreamReader
)在BCL.
并string
进行了说明像关键字(C#参考)或类似的任何基本的C#语言构造(例如,for
,while
,default
).
参考.
正如所指出的,它们是同一个东西,string
只是一个别名String
.
对于它的价值,我使用字符串来声明类型 - 变量,属性,返回值和参数.这与使用其他系统类型一致- int, bool, var
等(虽然Int32
和Boolean
也是正确的).
我String
在String类上使用静态方法时使用,比如String.Split()
或String.IsNullOrEmpty()
.我觉得这更有意义,因为这些方法属于一个类,它与我使用其他静态方法的方式一致.
这两者没有区别.您可以在代码中使用其中任何一个.
System.String
是mscorlib
命名空间中定义的类(引用类型)System
.换句话说,System.String
是一种类型CLR
.
string
是一个关键字 C#
如果你写这个,字符串等于VS2015中的System.String
System.String str;
比编译器将显示优化它的潜在修复,并在应用该修复后它将看起来像这样
string str;
我更喜欢使用,string
因为这种类型的使用非常多,我不希望语法高亮显示器将其与所有其他类混合使用.虽然它是一个类,但它更像是一个原语,因此我认为不同的高光颜色是合适的.
如果您右键单击string
关键字并Go to definition
从上下文菜单中选择它将带您进入String
该类 - 它只是语法糖,但它提高了可读性imo.
一个字符串是一个连续的字符集,用来表示文本.
甲字符串对象是System.Char对象的有序集合表示的字符串; System.Char对象对应于UTF-16代码单元.
String对象的值是System.Char对象的顺序集合的内容,该值是不可变的(即,它是只读的).
有关字符串不变性的更多信息,请参阅msdn中的Immutability和StringBuilder类部分.
内存中String对象的最大大小为2GB,即大约10亿个字符.
注意:答案摘自msdn帮助部分.您可以在备注部分下的msdn String Class主题中查看完整内容
在C#中,string是System.String(String)的简短版本.它们基本上意味着同样的事情.
就像有人提到的那样,它就像,bool
并Boolean
没有太大的区别......
据我所知,string
只是一个别名System.String
,并存在类似的别名bool
,object
,int
...唯一的细微差别是,你可以使用string
不带"使用System;
"指令,而字符串需要它(否则你应该指定System.String
全) .
关于哪个最好用,我想这是一个品味问题.我个人更喜欢string
,但我不是宗教问题.
字符串:代表一个类
字符串:代表别名
string
是的简称System.String
。
String
或是System.String
中的字符串名称CTS(Common Type System)
。
string是.NET Framework中String的别名。
实际上是“字符串” System.String.
我要说的是它们是可互换的,在何时何地使用一种或另一种没有什么区别。
最好与您使用过的一致。
对于它的价值,我string
用来声明类型-变量,属性,返回值和参数。这与其他系统类型(int, bool, var
等等)的使用是一致的(尽管Int32
并且Boolean
也是正确的)。
在String类(例如String.Split()
或)上使用静态方法时,我使用String String.IsNullOrEmpty()
。我觉得这更有意义,因为这些方法属于一个类,并且与我使用其他静态方法的方式一致。
如您所知string
,只是的别名System.String
。但是我该怎么用呢?这只是个人喜好。
就我而言,我喜欢使用string
而不是使用,System.String
因为String
需要名称空间using System;
或全名System.String
。
因此,我相信别名 string
是为简单起见而创建的,我喜欢它!
string是的快捷方式System.String
。唯一的区别是您不需要引用System.String
名称空间。因此,使用字符串比使用String更好。
String
是 的类string
。如果您System
从 using 语句中删除命名空间,您可以看到它String
已经消失但string
仍然存在。string
是字符串的关键字。Like
所以关键字只是一些使用类的词。这些关键字是由 C# 指定的(所以是 Microsoft,因为 C# 是 Microsoft 的)。简而言之,没有区别。使用. 那没关系。他们是一样的。int and Int32
short and Int16
long and Int64string or String
以上基本都是正确的。可以查一查。只写一个简短的方法
public static void Main()
{
var s = "a string";
}
编译它,并打开.exe
与ildasm
看
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 8 (0x8)
.maxstack 1
.locals init ([0] string s)
IL_0000: nop
IL_0001: ldstr "a string"
IL_0006: stloc.0
IL_0007: ret
} // end of method Program::Main
然后更改var
为string
and String
,编译,打开 withildasm
并查看IL
没有变化。它还显示语言的创建者更喜欢string
在定义变量时(剧透:在调用他们喜欢的成员时String
)。
通常使用C#关键字声明变量。实际上,每种C#类型在.NET中都有一个等效项。再举一个例子,C#中的short和int映射到.NET中的Int16和Int32。因此,从技术上讲,string和String之间没有区别,但是在C#中,string是.NET框架中String类的别名。