C# 中的 String 和 string 有什么区别?
题
例子 (注意案例):
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);
这是微软倾向于使用的风格 他们的例子.
看来该领域的指导可能已经改变,因为 风格警察 现在强制使用 C# 特定别名。
其他提示
只是为了完整起见,这里是相关信息的脑转储......
正如其他人指出的那样, 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
这只是规范定义枚举声明的方式问题 - 冒号后面的部分必须是 整体型 生产,这是一种象征 sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
...与 类型 例如,变量声明所使用的生产。它并不表明任何其他差异。
最后,说到使用哪个:我个人在实现过程中到处都使用别名,但对于任何 API 都使用 CLR 类型。在实施方面,您使用哪种方式确实并不重要——团队之间的一致性很好,但没有其他人会关心。另一方面,如果您引用 API 中的类型,请以语言中立的方式进行操作,这一点确实很重要。一个方法叫做 ReadInt32
是明确的,而称为 ReadInt
需要解释。调用者可能使用一种定义了 int
别名为 Int16
, , 例如。.NET 框架设计者遵循了这种模式,很好的例子是 BitConverter
, BinaryReader
和 Convert
类。
String
代表 System.String
它是.NET Framework 类型。 string
是一个别名 在 C# 语言中 System.String
. 。两者都编译为 System.String
在伊利诺伊州 (中间语言),所以没有区别。选择你喜欢的并使用它。如果你用 C# 编码,我更喜欢 string
因为它是 C# 类型别名并且为 C# 程序员所熟知。
我也可以这么说 (int
, System.Int32
) ETC..
我听过的关于在 C# 中使用提供的类型别名的最佳答案来自 Jeffrey Richter 在他的书中 通过 C# 进行 CLR. 。以下是他的3个理由:
- 我见过很多开发者很困惑,不知道是否要使用 细绳 或者 细绳 在他们的代码中。因为在 C# 中,字符串(关键字)精确映射到 System.String(FCL 类型),所以没有区别,都可以使用。
- 在 C# 中, 长的 映射到 系统.Int64, ,但是用不同的编程语言, 长的 可以映射到 整数16 或者 整数32. 。事实上,C++/CLI 确实将 long 视为 整数32. 。如果某人习惯于使用不同的编程语言进行编程,则阅读一种语言的源代码时很容易会误解代码的意图。事实上,大多数语言甚至不会对待 长的 作为关键字,并且不会编译使用它的代码。
- FCL 有许多方法,这些方法将类型名称作为其方法名称的一部分。例如, 二进制阅读器 type 提供了诸如 读取布尔值, 读Int32, 读单, ,等等,以及 系统.转换 type 提供了诸如 转换为布尔值, 转为Int32, 至单身人士, , 等等。虽然编写下面的代码是合法的,但是带有 float 的行对我来说感觉很不自然,并且不明显该行是正确的:
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good
所以你有它。我认为这些都是非常好的观点。然而,我发现自己没有在自己的代码中使用杰弗里的建议。也许我太困在我的 C# 世界中,但我最终试图让我的代码看起来像框架代码。
string
是一个保留字,但是 String
只是一个类名。这意味着 string
不能单独用作变量名。
如果出于某种原因你想要一个名为 细绳, ,您只会看到这些编译中的第一个:
StringBuilder String = new StringBuilder(); // compiles
StringBuilder string = new StringBuilder(); // doesn't compile
如果你真的想要一个名为 细绳 您可以使用 @
作为前缀:
StringBuilder @string = new StringBuilder();
另一个关键区别:Stack Overflow 以不同的方式突出它们。
有一点不同 - 你不能使用 String
没有 using System;
预先。
上面已经介绍过了;但是,你不能使用 string
反思中;你必须使用 String
.
System.String
是 .NET 字符串类 - 在 C# 中 string
是一个别名 System.String
- 所以在使用上它们是相同的。
至于指导方针,我不会太陷入困境,只要使用你想要的任何东西 - 生活中有更重要的事情,无论如何代码都会是相同的。
如果您发现自己构建的系统需要指定您正在使用的整数的大小,因此倾向于使用 Int16
, Int32
, UInt16
, UInt32
ETC。那么使用起来可能看起来更自然 String
- 当在不同的 .net 语言之间移动时,它可能会让事情更容易理解 - 否则我会使用 string 和 int。
我更喜欢大写的 .NET
出于格式原因而使用类型(而不是别名)。这 .NET
类型的颜色与其他对象类型相同(毕竟,值类型是正确的对象)。
条件关键字和控制关键字(例如 if
, switch
, , 和 return
) 为小写字母,颜色为深蓝色(默认情况下)。我宁愿在使用和格式上没有分歧。
考虑:
String someString;
string anotherString;
string
和 String
在所有方面都相同(除了大写“S”)。无论哪种方式都不会影响性能。
小写 string
由于语法高亮,在大多数项目中是首选
C#是一种与CLR一起使用的语言。
string
是 C# 中的一种类型。
System.String
是 CLR 中的一种类型。
当您将 C# 与 CLR 一起使用时 string
将被映射到 System.String
.
理论上,您可以实现一个生成 Java 字节码的 C# 编译器。该编译器的合理实现可能会映射 string
到 java.lang.String
为了与 Java 运行时库进行互操作。
这个YouTube 视频实际演示了它们的不同之处。
但现在需要一个很长的文字答案。
当我们谈论 .NET
有两种不同的东西,其中之一是 .NET
框架和其他有语言( C#
, VB.NET
等)使用该框架。
"System.String
“又名“String”(大写“S”)是 .NET
框架数据类型,而“string”是 C#
数据类型。
简而言之,“String”是“string”的别名(同一个东西用不同的名字称呼)。因此从技术上讲,下面的代码语句将给出相同的输出。
String s = "I am String";
或者
string s = "I am String";
以同样的方式,其他 C# 数据类型也有别名,如下所示:-
目的: System.Object
, , 细绳: System.String
, ,布尔: System.Boolean
, , 字节: System.Byte
, 字节: System.SByte
, , 短的: System.Int16
等等
现在从程序员的角度来看,这是一个价值百万美元的问题 那么何时使用“String”和“string”?
避免混淆的第一件事是始终使用其中一个。但从最佳实践的角度来看,当您进行变量声明时,最好使用“string”(小写的“s”),而当您将其用作类名时,则首选“String”(大写的“S”)。
在下面的代码中,左侧是一个变量声明,它使用“字符串”进行声明。在右侧,我们调用一个方法,因此“String”更合理。
string s = String.ToUpper() ;
小写 string
是一个别名 System.String
。它们是相同的 C#
.
关于是否应该使用系统类型存在争议(System.Int32
, System.String
, 等)类型或 C# aliases
(int
, string
, , ETC)。我个人认为你应该使用 C# aliases
, ,但这只是我个人的偏好。
string
只是一个别名 System.String
. 。编译器将同等对待它们。
唯一的实际区别是您提到的语法突出显示,并且您必须编写 using System
如果你使用 String
.
两者都是一样的。但从编码指南的角度来看,最好使用 string
代替 String
. 。这是开发人员通常使用的。例如而不是使用 Int32
我们用 int
作为 int
是别名 Int32
仅供参考“关键字字符串只是预定义类的别名 System.String
。” -C#语言规范4.2.3http://msdn2.microsoft.com/En-US/library/aa691153.aspx
正如其他人所说,他们是一样的。默认情况下,StyleCop 规则将强制您使用 string
作为 C# 代码风格最佳实践,引用时除外 System.String
静态函数,例如 String.Format
, String.Join
, String.Concat
, , ETC...
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)
可能会(取决于 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"
无法转换成它。
如果您喜欢这类事情,使用系统类型可以更轻松地在 C# 和 VB.Net 之间进行移植。
与其他程序员中似乎常见的做法相比,我更喜欢 String
超过 string
, ,只是为了强调这样一个事实 String
正如乔恩·斯基特(Jon Skeet)提到的那样,是一种引用类型。
string
是以下的别名(或简写) System.String
. 。这意味着,通过输入 string
我们的意思是 System.String
. 。您可以在思考链接中阅读更多内容: “string”是 System.String 的别名/简写。
细绳 (System.String
) 是基类库中的一个类。string(小写)是 C# 中的保留工作,是 System.String 的别名。Int32 与 int 的情况类似 Boolean vs. bool
. 。这些 C# 语言特定关键字使您能够以类似于 C 的风格声明基元。
我只想将其添加到 Ritchers 书中的 lfousts 答案中:
C#语言规范指出:“就样式而言,使用关键字而不是使用完整的系统类型名称。”我不同意语言规范;我更喜欢使用FCL类型名称,并完全避免使用原始类型名称。实际上,我希望编译器甚至没有提供原始类型名称,并强迫开发人员改用FCL类型名称。以下是我的理由:
我见过很多开发者很困惑,不知道是否要使用 细绳或者 细绳 在他们的代码中。因为在 C# 中 细绳 (关键字)完全映射到 系统字符串 (整箱型)没有区别,都可以使用。同样,我听说一些开发人员说 整数 当应用程序在32位OS上运行时,代表一个32位整数,并且当应用程序在64位OS上运行时,它代表64位整数。这种说法绝对是错误的:在 C# 中,一个 整数 总是映射到 系统.Int32, ,因此,它代表一个32位整数,无论代码正在运行什么操作系统。如果程序员会使用 整数32 在他们的代码中,也消除了这种潜在的混乱。
在 C# 中, 长的 映射到 系统.Int64, ,但是用不同的编程语言, 长的可以映射到 整数16 或者 整数32. 。事实上,C++/CLI 确实处理 长的 作为 整数32。如果某人习惯于用不同的编程语言编程,则以一种语言阅读源代码很容易误解该代码的意图。事实上,大多数语言甚至不会对待 长的 作为关键字,不会编译使用它的代码。
FCL 有许多方法,这些方法将类型名称作为其方法名称的一部分。例如, 二进制阅读器 type 提供了诸如 读取布尔值, 读Int32, 读单, ,等等,以及 系统.转换 type 提供了诸如 转换为布尔值, 转为Int32, 至单身人士, , 等等。尽管编写以下代码是合法的,但与 漂浮 对我来说感觉很不自然,这并不明显正确:
BinaryReader br = new BinaryReader(...); float val = br.ReadSingle(); // OK, but feels unnatural Single val = br.ReadSingle(); // OK and feels good
许多使用C#的程序员倾向于忘记其他编程语言可以针对CLR使用,因此,C#isisms渗入了类库代码。例如,Microsoft的FCL几乎专门用C#编写,FCL团队的开发人员现在将方法引入了库,例如 大批的 获取长长度, ,它返回一个 整型64 值是一个 长的 在C#中,而不是其他语言(例如C ++/CLI)。另一个例子是 System.Linq.Enumerable的 长计数 方法。
在我读完完整的段落之前,我没有得到他的意见。
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
.
关于这个问题有一个引用来自 丹尼尔·索利斯的书.
所有预定义的类型都直接映射到基础.NET类型。C#类型名称(字符串)只是.NET类型(String或System.String)的别名,因此使用.NET名称在句法上效果很好,尽管不建议使用。在C#程序中,您应该使用C#名称而不是.NET名称。
细绳 是一个关键字,不能使用字符串作为标识符。
细绳 不是关键字,您可以将其用作标识符:
例子
string String = "I am a string";
关键词 string
是一个别名 System.String
除了关键字问题外,这两者完全等效。
typeof(string) == typeof(String) == typeof(System.String)
是的,他们之间没有区别,就像 bool
和 Boolean
.
两者没有区别—— string
, 然而,在考虑其他开发人员的源代码时,似乎是首选。