[c#] Was ist der Unterschied zwischen String und String in C #?



Answers

Nur der Vollständigkeit halber, hier ist ein Braindump von verwandten Informationen ...

Wie bereits erwähnt, ist string ein Alias ​​für System.String . Sie kompilieren nach demselben Code, so dass zur Ausführungszeit überhaupt kein Unterschied besteht. Dies ist nur einer der Aliase in C #. Die vollständige Liste ist:

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

Abgesehen von string und object sind die Aliase alle auf Werttypen. decimal ist ein Werttyp, aber kein primitiver Typ in der CLR. Der einzige primitive Typ, der keinen Alias ​​hat, ist System.IntPtr .

In der Spezifikation werden die Aliase des Werttyps als "einfache Typen" bezeichnet. Literale können für konstante Werte jedes einfachen Typs verwendet werden; Für keine anderen Werttypen sind Literalformen verfügbar. (Vergleichen Sie dies mit VB, das DateTime Literale erlaubt und auch einen Alias ​​enthält.)

Es gibt einen Umstand, in dem Sie die Aliase verwenden müssen: wenn Sie den zugrunde liegenden Typ einer Aufzählung explizit angeben. Zum Beispiel:

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

Das sbyte , wie die Spezifikation enum-Deklarationen definiert - der Teil nach dem Doppelpunkt muss die Produktion vom Integraltyp sein , was ein Token von sbyte , byte , short , ushort , int , uint , long , ulong , char . .. im Gegensatz zu einer Typerzeugung, wie sie beispielsweise von Variablendeklarationen verwendet wird. Es gibt keinen anderen Unterschied.

Schließlich, wenn es darum geht zu verwenden: persönlich verwende ich die Aliase überall für die Implementierung, aber den CLR-Typ für alle APIs. Es ist wirklich nicht so wichtig, was Sie in Bezug auf die Implementierung verwenden - Konsistenz in Ihrem Team ist nett, aber niemand wird sich darum kümmern. Auf der anderen Seite ist es wirklich wichtig, dass Sie, wenn Sie in einer API auf einen Typ verweisen, dies auf eine sprachneutrale Art tun. Eine Methode namens ReadInt32 ist eindeutig, wohingegen eine Methode namens ReadInt eine Interpretation erfordert. Der Aufrufer könnte beispielsweise eine Sprache verwenden, die einen int Alias ​​für Int16 definiert. Die .NET-Framework-Designer sind diesem Muster gefolgt, gute Beispiele sind die BitConverter , BinaryReader und Convert Klassen.

Question

Beispiel ( beachten Sie den Fall ):

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

Was sind die Richtlinien für die Verwendung von jedem? Und was sind die Unterschiede ?




New answer after 6 years and 5 months (procrastination).

While string is a reserved C# keyword that always has a fixed meaning, String is just an ordinary identifier which could refer to anything. Depending on members of the current type, the current namespace and the applied using directives and their placement, String could be a value or a type distinct from global::System.String .

I shall provide two examples where using directives will not help .

First, when String is a value of the current type (or a local variable):

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

  void Example()
  {
    var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
  }
}

The above will not compile because IEnumerable<> does not have a non-static member called Format , and no extension methods apply. In the above case, it may still be possible to use String in other contexts where a type is the only possibility syntactically. For example String local = "Hi mum!"; could be OK (depending on namespace and using directives).

Worse: Saying String.Concat(someSequence) will likely (depending on using s) go to the Linq extension method Enumerable.Concat . It will not go to the static method string.Concat .

Secondly, when String is another type , nested inside the current type:

class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

Neither statement in the Example method compiles. Here String is always a piano string , MyPiano.String . No member ( static or not) Format exists on it (or is inherited from its base class). And the value "Goodbye" cannot be converted into it.




Die beste Antwort, die ich jemals über die Verwendung der bereitgestellten Typaliasnamen in C # gehört habe, kommt von Jeffrey Richter in seinem Buch CLR Via C # . Hier sind seine 3 Gründe:

  • Ich habe eine Reihe von Entwicklern verwirrt gesehen, die nicht wussten, ob sie in ihrem Code String oder String verwenden sollten. Da in C # die Zeichenfolge (ein Schlüsselwort) genau auf System.String (ein FCL-Typ) abgebildet wird, gibt es keinen Unterschied und beide können verwendet werden.
  • In C #, lange Maps zu System.Int64 , aber in einer anderen Programmiersprache, könnte lange zu einem Int16 oder Int32 zuordnen . Tatsächlich behandelt C ++ / CLI tatsächlich lange als Int32 . Jemand, der Quellcode in einer Sprache liest, könnte die Absicht des Codes leicht falsch interpretieren, wenn er oder sie daran gewöhnt wäre, in einer anderen Programmiersprache zu programmieren. Tatsächlich werden die meisten Sprachen nicht einmal lange als Schlüsselwort behandelt und kompilieren keinen Code, der sie verwendet.
  • Die FCL hat viele Methoden, die Typnamen als Teil ihrer Methodennamen enthalten. Der BinaryReader- Typ bietet beispielsweise Methoden wie ReadBoolean , ReadInt32 , ReadSingle usw. an, und der System.Convert- Typ bietet Methoden wie ToBoolean , ToInt32 , ToSingle usw. an. Obwohl es legal ist, den folgenden Code zu schreiben, fühlt sich die Zeile mit Float sehr unnatürlich an und es ist nicht offensichtlich, dass die Zeile korrekt ist:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // Ok, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

So, da hast du es. Ich denke, das sind alles wirklich gute Punkte. Ich finde jedoch nicht, dass ich Jeffreys Rat in meinem eigenen Code benutze. Vielleicht bin ich zu fest in meiner C # -Welt, aber am Ende versuche ich, meinen Code wie den Framework-Code aussehen zu lassen.




Wie die anderen sagen, sind sie gleich. StyleCop-Regeln erzwingen standardmäßig die Verwendung von string als C # -Code-Best Practice, außer wenn auf statische System.String Funktionen wie String.Format , String.Join , String.Concat usw. String.Concat wird.




System.String ist die .NET-String-Klasse - in C # ist string ein Alias ​​für System.String - also sind sie in der Verwendung identisch.

Was die Richtlinien betrifft, würde ich nicht zu festgefahren werden und einfach nur das verwenden, was man möchte - es gibt wichtigere Dinge im Leben und der Code wird sowieso derselbe sein.

Wenn Sie Systeme erstellen, bei denen es notwendig ist, die Größe der von Ihnen verwendeten Ganzzahlen anzugeben und Int16 , Int32 , UInt16 , UInt32 usw. zu verwenden, dann könnte es natürlicher erscheinen, String zu verwenden - und wenn Sie sich zwischen verschiedenen bewegen .net Sprachen könnte es die Dinge verständlicher machen - sonst würde ich string und int verwenden.




Zu spät zur Party kommen: Ich benutze die CLR-Typen zu 100% (na ja, außer wenn man gezwungen ist , den C # -Typ zu verwenden, aber ich erinnere mich nicht, wann das letzte mal war).

Ich habe das vor Jahren angefangen, wie in den CLR-Büchern von Ritchie. Es machte für mich Sinn, dass alle CLR-Sprachen letztendlich in der Lage sein müssen, den Satz von CLR-Typen zu unterstützen, so dass die Verwendung der CLR-Typen selbst klareren und möglicherweise mehr "wiederverwendbaren" Code zur Verfügung stellte.

Jetzt, wo ich es seit Jahren mache, ist es eine Gewohnheit und ich mag die Färbung, die VS für die CLR-Typen zeigt.

Der einzige wirkliche Wermutstropfen ist, dass die automatische Vervollständigung den C # -Typ verwendet, sodass ich am Ende automatisch typisierte Typen neu tippe, um stattdessen den CLR-Typ anzugeben.

Auch jetzt, wenn ich "int" oder "string" sehe, sieht es für mich wirklich falsch aus, wie ich auf den C-Code von 1970 schaue.




Es gibt einen Unterschied - Sie können String ohne using System; vorher.




Kleinschreibung ist ein Alias ​​für System.String . Sie sind in C# identisch.

Es gibt eine Debatte darüber, ob Sie die System.Int32 ( System.Int32 , System.String , usw.) oder die C# aliases ( int , string usw.) verwenden sollten. Ich persönlich glaube, dass Sie die C# aliases , aber das ist nur meine persönliche Vorliebe.




Dieses YouTube- Video zeigt praktisch, wie sie sich unterscheiden.

Aber jetzt für eine lange Textantwort.

Wenn wir über .NET sprechen, gibt es zwei verschiedene Dinge, nämlich .NET Framework und das andere gibt es Sprachen ( C# , VB.NET usw.), die dieses Framework verwenden.

" System.String " aka "String" (Großbuchstabe "S") ist ein .NET Framework-Datentyp, während "Zeichenfolge" ein C# System.String ist.

Kurz gesagt, "String" ist ein Alias ​​(der gleiche Name mit verschiedenen Namen) von "String". Technisch werden also beide untenstehenden Anweisungen die gleiche Ausgabe liefern.

String s = "I am String";

oder

string s = "I am String";

Auf die gleiche Weise gibt es Aliase für andere c # -Datentypen wie folgt:

Objekt: System.Object , Zeichenfolge: System.String , bool: System.Boolean , Byte: System.Byte , sbyte: System.SByte , kurz: System.Int16 und so weiter

Jetzt die Millionen-Dollar-Frage aus der Sicht des Programmierers Also, wann "String" und "String" zu verwenden?

Als erstes, um Verwirrung zu vermeiden, benutze eins von ihnen konsequent. Aus Sicht der besten Praktiken ist es bei der Variablendeklaration jedoch sinnvoll, "string" (kleines "s") zu verwenden, und wenn Sie es als Klassennamen verwenden, wird "String" (Großbuchstabe "S") bevorzugt.

Im folgenden Code ist die linke Seite eine Variablendeklaration und wird mit "string" deklariert. Auf der rechten Seite rufen wir eine Methode auf, so dass "String" sinnvoller ist.

string s = String.ToUpper() ;



Entgegen dem, was bei anderen Programmierern üblich ist, bevorzuge ich String over string , um nur die Tatsache hervorzuheben, dass String ein Referenztyp ist, wie Jon Skeet erwähnte.




string und String sind in jeder Hinsicht identisch (mit Ausnahme des Großbuchstabens "S"). Es gibt keine Auswirkungen auf die Performance.

Kleinbuchstaben werden in den meisten Projekten aufgrund der Syntaxhervorhebung bevorzugt




Es ist eine Frage der Konvention, wirklich. "string" sieht nur mehr wie C / C ++ - Stil aus. Die allgemeine Konvention besteht darin, die von der von Ihnen gewählten Sprache bereitgestellten Verknüpfungen zu verwenden (int / Int for Int32). Dies gilt auch für "Objekt" und "Dezimal".

Theoretisch könnte das helfen, Code in einen zukünftigen 64-Bit-Standard zu portieren, in dem "int" Int64 bedeuten könnte, aber das ist nicht der Punkt, und ich würde erwarten, dass jeder Upgrade-Assistent irgendwelche "int" -Verweise auf "Int32" ändert sicher sein.




Yes, that's no difference between them, just like the bool and Boolean .




String ( System.String ) ist eine Klasse in der Basisklassenbibliothek. string (Kleinschreibung) ist eine reservierte Arbeit in C #, die ein Alias ​​für System.String ist. Int32 vs int ist eine ähnliche Situation wie Boolean vs. bool . Diese C # -Sprachwörter ermöglichen es Ihnen, Grundelemente in einem ähnlichen Stil wie C zu deklarieren.




There is no difference between the two - string , however, appears to be the preferred option when considering other developers' source code.




Related