String.Format - wie es funktioniert und wie man benutzerdefinierte Formatstrings implementiert

79

Mit ist String.Format()es möglich, beispielsweise DateTimeObjekte auf viele verschiedene Arten zu formatieren . Jedes Mal, wenn ich nach einem gewünschten Format suche, muss ich mich im Internet umsehen. Fast immer finde ich ein Beispiel, das ich verwenden kann. Zum Beispiel:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

Aber ich habe keine Ahnung, wie es funktioniert und welche Klassen diese "magischen" zusätzlichen Zeichenfolgen unterstützen.

Meine Fragen sind also:

  1. Wie String.Formatordnen Sie die zusätzlichen Informationen MM/dd/yyyyeinem String-Ergebnis zu?
  2. Unterstützen alle Microsoft-Objekte diese Funktion?
    Ist das irgendwo dokumentiert?
  3. Ist es möglich, so etwas zu tun:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())
hwcverwe
quelle
Sie können einen Blick auf dieses codeproject.com/Articles/6533/Custom-String-Formatting-in-NET
V4Vendetta

Antworten:

88

String.FormatOrdnet jedes der Token in der Zeichenfolge ( {0}usw.) dem entsprechenden Objekt zu: http://msdn.microsoft.com/en-us/library/system.string.format.aspx

Optional wird eine Formatzeichenfolge bereitgestellt:

{ index[,alignment][ : formatString] }

Wenn angegeben formatString, muss das entsprechende Objekt IFormattable und insbesondere die ToStringMethode implementieren , die formatStringdie entsprechende formatierte Zeichenfolge akzeptiert und zurückgibt: http://msdn.microsoft.com/en-us/library/system.iformattable.tostring.aspx

Es IFormatProviderkann auch ein verwendet werden, mit dem grundlegende Formatierungsstandards / -standards usw. erfasst werden können. Beispiele hier und hier .

Also die Antworten auf Ihre Fragen in der Reihenfolge:

  1. Es verwendet die Methode der IFormattableSchnittstelle ToString()für das DateTimeObjekt und übergibt die MM/dd/yyyyFormatzeichenfolge. Es ist diese Implementierung, die die richtige Zeichenfolge zurückgibt.

  2. Jedes Objekt, das implementiert, IFormattableunterstützt diese Funktion. Sie können sogar Ihre eigenen schreiben!

  3. Ja, siehe oben.

Yamen
quelle
10
+1 für die Verknüpfung mit der Dokumentation . "Im Internet suchen" kann in Ordnung sein. Wenn Sie jedoch ein tieferes Verständnis benötigen, sollten Sie das Handbuch lesen.
MarkJ
Gute Antwort, aber können Sie mir sagen, wo ich für jede implementierte Klasse IFormattablefinden kann, wo ich die zulässigen formatStrings finden kann. Zum Beispiel unterstützt DateTime (auf meinem Kopf) y M d h m sund mehr. Nummeric-Typen unterstützen die CWährung, aber das ist nicht alles, was ich aus der Suche in der Umgebung und nicht aus der Microsoft-Dokumentation weiß.
Hwcverwe
@hwcverwe - Bei fast jeder Google-Suche wird die MSDN-Dokumentation an oder nahe der Spitze einer Suche nach einem Objekt platziert. ToString-Suche. Es wird keine einzelne Seite geben, auf der der ToString (...) für jedes Objekt angezeigt wird - es gibt möglicherweise eine "unendliche" Anzahl davon, da standardmäßig alle Objekte mindestens ToString () implementieren, jedoch nicht unbedingt ToString (Format).
Wonko der Gesunde
3
@hwcverwe Formatierungstypen
Vladimir
20

Nach meinem Verständnis müssten Sie IFormattable in Ihrer Klasse implementieren, um dies zu unterstützen. Das hat dann die Methode ToString, die die Parameter übernimmt, die Sie an String.Format übergeben.

Hier ist ein Beispiel.

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())
Dean Thomas
quelle
5
  1. Überprüfen Sie die offiziellen MSDN-Dokumente. Eine vollständige Liste der Zeichenfolgen im DateTime-Format finden Sie hier: http://msdn.microsoft.com/en-us/library/az4se3k1.aspx . Es gibt in der Tat einige "magische" Saiten.

  2. Soweit ich weiß, haben nicht alle Typen eine "interessante" Formatierung, aber alle Typen unterstützen ToString(). Wenn Sie ein eingebautes Objekt formatieren müssen, können Sie eine Erweiterungsmethode hinzufügen. In der Regel wird die Formatierung jedoch an jeder Stelle bereitgestellt, an der sie benötigt wird (oder anders ausgedrückt, ich habe nur benutzerdefinierte Formatierer für meine eigenen Typen geschrieben). .

  3. Ja, Sie können Ihre eigenen Daten schreiben. Wenn Sie Daten haben, die auf unterschiedliche Weise formatiert werden können, sollten Sie wahrscheinlich einen benutzerdefinierten Formatierer schreiben, indem Sie IFormattable implementieren. Weitere Informationen finden Sie in den Dokumenten hier: http://msdn.microsoft.com/en-us/ library / system.iformattable.aspx . Es ist ziemlich einfach, Sie überprüfen einfach die bereitgestellten Zeichenfolgen und schreiben Ihre Daten basierend auf diesen auf. Hinter den Kulissen gibt es keine Magie :-)

Steve
quelle
4

Unter der Decke macht String.Format etwas wie folgt:

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

Für Ihre Fragen,

  1. Wie ordnet String.Format die zusätzlichen Informationen MM / TT / JJJJ einem String-Ergebnis zu?

    Wie oben angegeben, wird nur der IFormattable .ToString (Zeichenfolgenformat, IFormatProvider-Anbieter) aufgerufen. Der Anbieter sagt Ihnen oft, was die Kultur Ihres Systems ist. Oft null, weil die Leute String.Format () nicht übergeben, wie Sie es in Ihrem Fall getan haben.

  2. Unterstützt alle Microsoft-Objekte diese Funktion? Ist das irgendwo dokumentiert?

    Alles, was IFormattable implementiert, funktioniert.

  3. Ist es möglich so etwas zu tun: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    Im Wesentlichen, wenn Sie möchten, dass Ihr eigenes Objekt etwas mit dem von Ihnen implementierten Format tut IFormattable.

Es gibt eine große Anzahl unterstützender Klassen und Enumeratoren, um sicherzustellen, dass die Formatzeichenfolgen weitgehend ähnlich sind. Mehr hier .

M Afifi
quelle
0

Ja, es ist möglich - es kann vollständig angepasst werden. Sehen Sie sich diesen Dokumentationslink zur benutzerdefinierten Formatierung von Datum und Uhrzeit an.

Wenn Sie ein eigenes Objekt haben, liegt es an Ihnen, die ToString()Methode zu überschreiben und alles auszugeben, was Sie für eine angemessene Darstellung halten. Sobald Sie dies getan haben, können Sie verwenden, String.Format("{0:MyCustomFormat}", new MyOwnClass())da dies implizit aufruftMyOwnClass.ToString()

Maciej
quelle
-1 - Das OP fragt nach mehr als nur der DateTimeFormatierung. Und nur ein Link ist keine Antwort.
Oded
1
Sehr hart. DateTime ist einer der Aspekte und ich habe meine Antwort erweitert, während Sie abgestimmt haben.
Maciej
6
Erweitern Sie die Antwort und posten Sie sie , und Sie werden nicht herabgestimmt.
Oded
0

Die Dokumentation zu den Daten finden Sie hier: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

Das sollte Ihnen genau sagen, was alle Datumsformatierungszeichen wie MM bedeuten.

Wenn Sie ändern möchten, wie eine Zeichenfolge für eine benutzerdefinierte Klasse ausgegeben wird, können Sie die ToString-Methode wie folgt überschreiben:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

und dann können Sie einfach so etwas tun myUser.ToString()und die von Ihnen angegebene Ausgabe erhalten.

Fiona - myaccessible.website
quelle
0

Und um Ihre dritte Frage zu beantworten: Mit dieser Syntax ist dies nicht möglich, aber Sie können Instanzen von IFormatProviderund ICustomFormatterfür einen Typ bereitstellen, den Sie nicht erstellt oder IFormattablein Ihrem Typ implementiert haben (obwohl dies grundsätzlich erweitert wird ToString).

phipsgabler
quelle