遍历字符串 - String和C#中的string有什么区别?
c语言遍历字符串 (20)
示例( 注意情况 ):
string s = "Hello world!";
String s = "Hello world!";
每种使用的准则是什么? 有什么区别 ?
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
始终是钢琴string MyPiano.String
。 不存在成员( static
或非static
) Format
(或从其基类继承)。 并且值"Goodbye"
不能转换为它。
C#是与CLR一起使用的语言。
string
是C#中的类型。
System.String
是CLR中的一种类型。
当您将C#与CLR string
一起使用时,将被映射到System.String
。
从理论上讲,您可以实现一个生成Java字节码的C#编译器。 为了与Java运行时库进行互操作,此编译器的明智实现可能会将string
映射到java.lang.String
。
string
是C#中System.String
的别名。
因此,从技术上讲,没有区别。 就像int
vs. System.Int32
。
就准则而言,通常建议您在每次引用对象时都使用string
。
例如
string place = "world";
同样,我认为如果需要专门引用该类,通常建议使用String
。
例如
string greet = String.Format("Hello {0}!", place);
这是Microsoft倾向于在示例中使用的样式。
似乎此区域中的指南可能已更改,因为StyleCop现在强制使用C#特定别名。
String
不是关键字,可以用作标识符,string
而是关键字,不能用作标识符。并且在功能上都相同。
System.String
是.NET字符串类-C# string
是System.String
的别名-因此在使用中它们是相同的。
至于指导原则,我不会陷入困境,只要使用您喜欢的任何方式,生活中就会有更重要的事情,而且代码无论如何都将是相同的。
如果您发现自己需要指定要使用的整数的大小的构建系统,因此倾向于使用Int16
, Int32
, UInt16
, UInt32
等。那么使用String
看起来更自然-并且在不同位置之间移动时.net语言可能会使事情更容易理解-否则我将使用string和int。
string
只是System.String
的别名。 编译器将相同地对待它们。
唯一实际的区别是您提到的语法高亮显示,并且如果使用String
则必须使用using System
编写。
string
是保留字,而String
只是类名。 这意味着string
本身不能用作变量名。
如果由于某种原因您想要一个名为string的变量,那么您只会看到以下第一个编译:
StringBuilder String = new StringBuilder(); // compiles
StringBuilder string = new StringBuilder(); // doesn't compile
如果您确实想要一个名为string的变量名,则可以使用@
作为前缀:
StringBuilder @string = new StringBuilder();
另一个重要的区别:堆栈溢出以不同的方式突出显示它们。
string
是的别名(或简称)System.String
。意思是通过键入string
我们的意思System.String
。您可以在think链接中阅读更多内容:'string'是System.String的别名/缩写。
有一个区别 -不using System;
就不能使用String
using System;
预先。
上面已经讲过了; 但是,不能在反射中使用string
。 您必须使用String
。
为了完整起见,这里有一些相关信息的摘要……
正如其他人指出的那样, 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进行比较,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
的方法ReadInt
需要解释。 例如,调用方可能使用的语言为Int16
定义了int
别名。 .NET框架设计人员遵循了这种模式, BitConverter
, BinaryReader
和Convert
类中的例子很好。
使用System类型可以使在C#和VB.Net之间进行移植更加容易,如果您喜欢这种事情的话。
我只想在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可以映射到Int16或Int32。实际上,C ++ / CLI确实将Int32视为长期使用。如果某人阅读一种语言的源代码,如果习惯于使用另一种编程语言进行编程,则很容易会误解该代码的意图。事实上,大多数语言甚至不会把长的关键字,将无法编译代码,使用它。
FCL有很多方法,这些方法的名称中包含类型名称。例如,BinaryReader类型提供诸如ReadBoolean,ReadInt32,ReadSingle等方法,而System.Convert类型提供诸如ToBoolean,ToInt32,ToSingle等方法。尽管编写以下代码是合法的,但带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团队的开发人员现在已将方法引入到库中,例如Array的GetLongLength,该方法返回的Int64值在C#中长,但是在其他语言中(例如C ++) / CLI)。另一个示例是System.Linq.Enumerable的LongCount方法。
在阅读全文之前,我没有听他的意见。
我听说过的关于在C#中使用提供的类型别名的最佳答案来自Jeffrey Richter在他的书CLR Via C#中 。 这是他的3个原因:
- 我看到许多开发人员感到困惑,他们不知道在他们的代码中使用string还是String 。 因为在C#中,字符串(关键字)精确地映射到System.String(FCL类型),所以没有区别,并且两者都可以使用。
- 在C#中, long映射到System.Int64 ,但是在另一种编程语言中, long可以映射到Int16或Int32 。 实际上,C ++ / CLI实际上确实像Int32一样对待。 如果某人阅读一种语言的源代码,如果习惯于使用另一种编程语言进行编程,则很容易会误解该代码的意图。 实际上,大多数语言甚至都不会将其视为关键字,也不会编译使用该关键字的代码。
- FCL有很多方法,这些方法的名称中包含类型名称。 例如, BinaryReader类型提供诸如ReadBoolean , ReadInt32 , ReadSingle等方法,而System.Convert类型提供诸如ToBoolean , ToInt32 , ToSingle等方法。 尽管编写以下代码是合法的,但带float的行对我来说感觉很不自然,并且显然该行是正确的:
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good
所以你有它。 我认为这些都是非常好的要点。 但是,我发现自己没有在自己的代码中使用Jeffrey的建议。 也许我在C#世界中陷于困境,但最终还是试图使我的代码看起来像框架代码。
没有区别。
C#关键字string
映射到.NET类型System.String
-它是一个别名,保留该语言的命名约定。
同样,int
映射到System.Int32
。
由于格式化的原因,我更喜欢使用大写的.NET
类型(而不是别名)。 .NET
类型的颜色与其他对象类型相同(毕竟,值类型是正确的对象)。
条件和控制关键字(例如if
, switch
和return
)为小写字母,颜色为深蓝色(默认情况下)。 我宁愿在使用和格式方面没有分歧。
考虑:
String someString;
string anotherString;
两者之间没有区别- string
但是,在考虑其他开发人员的源代码时,似乎是首选。
反对什么似乎其他程序员是常有的事,我更喜欢String
过string
,只是为了强调一个事实,即String
是引用类型,如乔恩斯基特提及。
是的,它们之间没有区别,就像bool
和一样Boolean
。
确实,这是惯例问题。string
看起来更像C / C ++风格。一般约定是使用您选择的语言提供的任何快捷方式(in / Int为Int32
)。这也适用于“对象” decimal
。
从理论上讲,这可以帮助将代码移植到将来的某些64位标准中,其中“ int”可能意味着Int64
,但这不是重点,我希望任何升级向导都可以将任何int
引用更改Int32
为安全。