这两者之间有什么不同,我应该使用哪一个?
string s = "Hello world!";
String s = "Hello world!";
我想在lfoust的回答中补充一句,出自Ritchers的书:
C#语言规范说明,“作为风格问题,使用关键字优于使用完整的系统类型名称。” 我不同意语言规范;我更喜欢使用FCL类型名称并完全避免使用基元类型名称。实际上,我希望编译器甚至不提供基元类型名称,而是强制开发人员改用FCL类型名称。以下是我的理由:
我看到很多开发人员困惑,不知道在代码中应该使用 string 还是 String。因为在C#中,string (关键字) 精确映射到 System.String (FCL类型),二者没有区别,可以任意使用。类似地,我听到一些开发人员说,int 表示32位整数当应用程序在32位操作系统上运行时,表示64位整数当应用程序在64位操作系统上运行时。这种说法是绝对错误的:在C#中,int 总是映射到 System.Int32,因此无论代码在哪个操作系统上运行,它都表示32位整数。如果程序员在代码中使用 Int32,那么这种潜在的混淆也可以消除。
在C#中,long 映射到 System.Int64,但在不同的编程语言中,long 可能映射到 Int16 或 Int32。事实上,C++/CLI将 long 视为 Int32。如果使用一种不同于自己通常使用的编程语言阅读源代码,很容易对代码意图产生误解。事实上,大多数语言甚至不会将 long 视为关键字,并且不会编译使用它的代码。
FCL有许多方法,其中类型名称作为方法名称的一部分。例如,BinaryReader 类型提供了诸如 ReadBoolean、ReadInt32、ReadSingle 等方法,而 System.Convert 类型提供了诸如 ToBoolean、ToInt32、ToSingle 等方法。虽然写以下代码是合法的,但我觉得带有 float 的行感觉非常不自然,不明显这行代码是否正确:
许多独立使用C#的程序员往往忘记其他编程语言也可以针对CLR进行开发,因此,C#中的惯用语会渗透到类库代码中。例如,微软的FCL几乎完全用C#编写,FCL团队的开发人员现在已将方法引入库中,比如Array的GetLongLength方法,在C#中返回一个Int64值,但在其他语言(如C++/CLI)中不是这样。另一个例子是System.Linq.Enumerable的LongCount方法。
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 与 int 的区别也类似于 Boolean vs. bool
。这些 C# 语言特定的关键字使您可以以类似于 C 的风格声明基本类型。
@JaredPar(一位C#编译器开发人员和 prolific SO 用户!)在这个问题上写了一篇很棒的博客文章。我认为值得在这里分享。这是对我们主题的一个不错的视角。
string
与String
不是风格辩论
在C#中,关键字[...]
string
有具体的含义。它是存在于核心运行时程序集中的类型System.String
。运行时本质上理解这种类型,并为.NET中的字符串提供开发人员所期望的功能。如果该类型不存在,则编译器在尝试解析代码行之前就会退出。因此,在C#代码中,string
具有精确、明确的含义。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; }
The actual meaning of
String
will always depend on name resolution. That means it depends on all the source files in the project and all the types defined in all the referenced assemblies. In short it requires quite a bit of context to know what it means.True that in the vast majority of cases
String
andstring
will bind to the same type. But usingString
still means developers are leaving their program up to interpretation in places where there is only one correct answer. WhenString
does bind to the wrong type it can leave developers debugging for hours, filing bugs on the compiler team, and generally wasting time that could’ve been saved by usingstring
.Another way to visualize the difference is with this sample:
string s1 = 42; // Errors 100% of the time String s2 = 42; // Might error, might not, depends on the code
Many will argue that while this is information technically accurate using
String
is still fine because it’s exceedingly rare that a codebase would define a type of this name. Or that whenString
is defined it’s a sign of a bad codebase.
你会发现,对于许多完全有效的目的,都定义了[...]
String
:反射帮助程序、序列化库、词法分析器、协议等。对于任何这些库,String
与string
之间的区别取决于代码使用的位置。
因此,请记住,当您看到String
与string
的争论时,这是关于语义而不是风格的问题。选择string可以为您的代码库提供清晰的含义。选择String
并没有错,但这将为未来留下意外的可能性。
注意:出于存档原因,我复制/粘贴了大部分博客文章。我忽略了一些部分,所以如果可以的话,请跳过并阅读blog post。
这实际上是一种惯例问题。使用string
更类似于C / C ++风格。一般的惯例是使用所选语言提供的任何快捷方式(例如,Int32
的int / Int)。这也适用于 "object" 和 decimal
。
从理论上讲,这可能有助于将代码移植到某个未来的64位标准中,其中"int"可能表示为Int64
,但这不是重点,我预计任何升级向导都会将任何int
引用更改为Int32
以确保安全。
String
不是一个关键字,可以用作标识符,而string
是一个关键字,不能用作标识符。从函数的角度来看,两者都是相同的。
迟来的派对:我一直100%使用CLR类型(好吧,除非被强制使用C#类型,但我记不得上次是什么时候了)。
多年前,我开始这样做,遵循Ritchie的CLR书籍。我认为所有CLR语言最终都必须支持CLR类型集合,因此自己使用CLR类型可以提供更清晰、可能更“可重用”的代码。
现在,我已经这样做了多年,这成了一种习惯,我喜欢VS为CLR类型显示的颜色。
唯一的问题是自动完成使用C#类型,所以我最终要重新输入自动生成的类型,以指定CLR类型。
此外,现在当我看到"int"或"string"时,它看起来对我来说就像是看着20世纪70年代的C代码一样错误。
没有区别。
C# 关键字 string
映射到 .NET 类型 System.String
- 它是一个别名,遵循语言的命名约定。
同样,int
映射到 System.Int32
。
这个问题在Daniel Solis的书中有一句话。
所有预定义类型都直接映射到底层的.NET类型。C#类型名称(例如string)只是.NET类型(String或System.String)的别名,因此在语法上使用.NET名称也可以正常工作,但这是不鼓励的。在C#程序中,您应该使用C#名称而不是.NET名称。
string 是一个关键字,你不能将 string 作为标识符。
String 不是一个关键字,你可以将它作为标识符:
示例
string String = "I am a string";
关键字string
是System.String
的别名。除了关键字之外,它们完全等同。
typeof(string) == typeof(String) == typeof(System.String)
是的,它们之间没有区别,就像 bool
和 Boolean
一样。
string
是 C# 语法的一个 词法 构造,而System.String
只是一种类型。无论任何规范中提到的 显式 差异如何,仍然存在这种隐含的差异,可能会带来一些歧义。语言本身必须以一种不需要考虑 BCL 中的特定类的方式支持string
。 - Kirk Wollstring
存在问题。需要缩写System.String
,但作为别名,它看起来非常相似,但不完全相同。然而,经过几年的C#编程,我认为,安全起见,可以直接使用string
和string.Format()
,不用担心System.String
。 - RolandSystem.String
类还在,而string
关键字仍然是它的别名,就像System.Int32
和int
一样。它们实际上是同一个东西。 - Craig Tullis