遍历字符串 - String和C#中的string有什么区别?




c语言遍历字符串 (20)

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或非staticFormat (或从其基类继承)。 并且值"Goodbye"不能转换为它。

示例( 注意情况 ):

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

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


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# stringSystem.String的别名-因此在使用中它们是相同的。

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

如果您发现自己需要指定要使用的整数的大小的构建系统,因此倾向于使用Int16Int32UInt16UInt32等。那么使用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();

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



有一个区别 -不using System;就不能使用String using System; 预先。


上面已经讲过了; 但是,不能在反射中使用string 。 您必须使用String


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

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

除了stringobject ,别名都是值类型。 decimal是一种值类型,但不是CLR中的原始类型。 没有别名的唯一基本类型是System.IntPtr

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

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

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

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

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


使用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可以映射到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方法。

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


我听说过的关于在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#世界中陷于困境,但最终还是试图使我的代码看起来像框架代码。


没有区别。

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

同样,int映射到System.Int32


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

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

考虑:

String someString; 
string anotherString; 

两者之间没有区别- string但是,在考虑其他开发人员的源代码时,似乎是首选。


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


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


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

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







alias