webentwicklung-frage-antwort-db.com.de

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

Mit String.Format() können beispielsweise DateTime Objekte auf viele verschiedene Arten formatiert werden. 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. Beispielsweise:

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 ordnet String.Format Die zusätzlichen Informationen MM/dd/yyyy Einem Zeichenfolgenergebnis zu?
  2. Unterstützen alle Microsoft-Objekte diese Funktion?
    Ist das irgendwo dokumentiert?
  3. Ist es möglich so etwas zu machen:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())
77
hwcverwe

String.Format Vergleicht jedes Token in der Zeichenfolge ({0} Usw.) mit dem entsprechenden Objekt: http://msdn.Microsoft.com/en-us/library/system). string.format.aspx

Optional wird eine Formatzeichenfolge bereitgestellt:

{ index[,alignment][ : formatString] }

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

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

Also die Antworten auf deine Fragen in der Reihenfolge:

  1. Es verwendet die ToString() -Methode der IFormattable -Schnittstelle für das DateTime -Objekt und übergibt die Formatzeichenfolge MM/dd/yyyy. Es ist diese Implementierung, die den richtigen String zurückgibt.

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

  3. Ja, siehe oben.

84
yamen

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 in 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())
18
Dean Thomas
  1. In den offiziellen MSDN-Dokumenten finden Sie eine vollständige Liste der DateTime-Formatzeichenfolgen: 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, aber normalerweise wird die Formatierung 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/ de-de/library/system.iformattable.aspx . Es ist ziemlich einfach, du überprüfst einfach die bereitgestellten Zeichenketten und schreibst deine Daten basierend darauf aus, es gibt keine Magie hinter den Kulissen :-)

4
Steve Haigh

Unter der Decke String.Format macht 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/dd/yyyy einem Zeichenfolgenergebnis zu?

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

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

    Alles, was IFormattable implementiert, funktioniert.

  3. Kann man so etwas machen: String.Format("{0:MyCustomFormat}, new MyOwnClass())

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

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

3
M Afifi

Ja, es ist möglich - es kann vollständig angepasst werden. Schauen Sie sich den Link this documentation zur benutzerdefinierten Formatierung von Datum und Uhrzeit an.

Wenn Sie ein eigenes Objekt haben, müssen Sie die ToString() -Methode überschreiben und alles ausgeben, was Sie für eine angemessene Darstellung halten. Sobald Sie dies tun, können Sie String.Format("{0:MyCustomFormat}", new MyOwnClass()) verwenden, da dies implizit MyOwnClass.ToString() aufruft.

0
Maciej

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 etwas wie myUser.ToString() tun und die von Ihnen angegebene Ausgabe erhalten.

Und um Ihre dritte Frage zu beantworten: Das ist mit dieser Syntax nicht möglich, aber Sie können Instanzen von IFormatProvider und ICustomFormatter für einen Typ bereitstellen, den Sie nicht erstellt oder IFormattable implementiert haben. in Ihrem Typ (obwohl das im Grunde ToString erweitert).

0
phg