Frage

Vergleichen

String.Format("Hello {0}", "World");

mit

"Hello {0}".Format("World");

Warum haben die .Net-Designer eine statische Methode einer Instanzmethode vorgezogen?Was denken Sie?

War es hilfreich?

Lösung

Ich kenne die Antwort eigentlich nicht, aber ich vermute, dass sie etwas mit dem Aspekt des direkten Aufrufs von Methoden für String-Literale zu tun hat.

Wenn ich mich richtig erinnere (ich habe das nicht wirklich überprüft, weil ich keine alte IDE zur Hand habe), hatten frühe Versionen der C#-IDE Probleme beim Erkennen von Methodenaufrufen für Zeichenfolgenliterale in IntelliSense, und das hat große Auswirkungen auf die Erkennbarkeit der API.Wenn das der Fall wäre, würde Ihnen die Eingabe von Folgendem nicht weiterhelfen:

"{0}".Format(12);

Wenn Sie zum Tippen gezwungen wurden

new String("{0}").Format(12);

Es wäre klar, dass es keinen Vorteil hätte, die Format-Methode zu einer Instanzmethode anstelle einer statischen Methode zu machen.

Die .NET-Bibliotheken wurden von vielen der gleichen Leute entworfen, die uns MFC gegeben haben, und insbesondere die String-Klasse weist eine starke Ähnlichkeit mit der CString-Klasse in MFC auf.MFC verfügt über eine Instanzformatmethode (die Formatierungscodes im Printf-Stil anstelle des geschweiften Klammerstils von .NET verwendet), was problematisch ist, da es kein CString-Literal gibt.In einer MFC-Codebasis, an der ich gearbeitet habe, sehe ich viel davon:

CString csTemp = "";
csTemp.Format("Some string: %s", szFoo);

was schmerzhaft ist.(Ich sage nicht, dass der obige Code eine großartige Möglichkeit ist, Dinge sogar in MFC zu erledigen, aber auf diese Weise haben die meisten Entwickler des Projekts anscheinend gelernt, wie man CString::Format verwendet.)Aufgrund dieser Herkunft kann ich mir vorstellen, dass die API-Designer versucht haben, eine solche Situation erneut zu vermeiden.

Andere Tipps

Weil die Format-Methode nichts mit dem aktuellen Wert einer Zeichenfolge zu tun hat.

Das stimmt für alle String-Methoden, da .NET-Strings unveränderlich sind.

Wenn es nicht statisch wäre, benötigen Sie zunächst eine Zeichenfolge.

Es tut:die Formatzeichenfolge.

Ich glaube, dass dies nur ein weiteres Beispiel für die vielen Designfehler der .NET-Plattform ist (und ich meine das nicht als Flamme;Ich finde das .NET-Framework immer noch den meisten anderen Frameworks überlegen.

Nun, ich schätze, man muss da ziemlich genau sein, aber wie die Leute sagen, ist es wegen der implizierten Semantik sinnvoller, wenn String.Format statisch ist.Halten:

"Hello {0}".Format("World"); // this makes it sound like Format *modifies* 
                             // the string, which is not possible as 
                             // strings are immutable.

string[] parts = "Hello World".Split(' ');    // this however sounds right, 
                                             // because it implies that you 
                                             // split an existing string into 
                                             // two *new* strings.

Das erste, was ich tat, als ich auf VS2008 und C#3 aktualisieren konnte, war Folgendes

public static string F( this string format, params object[] args )
{
    return String.Format(format, args);
}

So kann ich jetzt meinen Code ändern

String.Format("Hello {0}", Name);

Zu

"Hello {0}".F(Name);

was mir damals am besten gefiel.Heutzutage (2014) kümmere ich mich nicht mehr darum, weil es nur ein weiterer Aufwand ist, das immer wieder zu jedem beliebigen Projekt, das ich erstelle, hinzuzufügen oder in irgendeiner Bibliothek voller Hilfsmittel zu verlinken.

Warum haben sich die .NET-Designer dafür entschieden?Wer weiß.Es scheint völlig subjektiv zu sein.Mein Geld ist für beides da

  • Java kopieren
  • Dem damaligen Autor gefiel es subjektiv besser.

Es gibt keine wirklich anderen triftigen Gründe, die ich finden kann

Ich denke, das liegt daran, dass Format keine Zeichenfolge per se akzeptiert, sondern eine „Formatzeichenfolge“.Die meisten Zeichenfolgen entsprechen Dingen wie „Bob Smith“ oder „1010 Main St“ oder was auch immer und nicht „Hallo {0}“. Im Allgemeinen fügen Sie diese Formatzeichenfolgen nur ein, wenn Sie versuchen, eine Vorlage zum Erstellen einer anderen zu verwenden string, wie eine Factory-Methode, und eignet sich daher für eine statische Methode.

Ich denke, das liegt daran, dass es sich um eine Erstellermethode handelt (ich bin mir nicht sicher, ob es einen besseren Namen gibt).Es nimmt lediglich das, was Sie ihm geben, und gibt ein einzelnes String-Objekt zurück.Es wird nicht auf ein vorhandenes Objekt angewendet.Wenn es nicht statisch wäre, benötigen Sie zunächst eine Zeichenfolge.

Weil die Format-Methode nichts mit dem aktuellen Wert einer Zeichenfolge zu tun hat.Der Wert der Zeichenfolge wird nicht verwendet.Es nimmt eine Zeichenfolge und gibt eine zurück.

Vielleicht haben es die .NET-Designer so gemacht, weil JAVA es so gemacht hat ...

Umarmen und erweitern.:) :)

Sehen: http://discuss.techinterview.org/default.asp?joel.3.349728.40

.NET-Strings sind unveränderlich
Daher macht es absolut keinen Sinn, eine Instanzmethode zu haben.

Nach dieser Logik sollte die String-Klasse keine Instanzmethoden haben, die geänderte Kopien des Objekts zurückgeben, obwohl dies der Fall ist eine Menge (Trim, ToUpper usw.).Darüber hinaus tun dies auch viele andere Objekte im Framework.

Ich stimme zu, dass, wenn sie daraus eine Instanzmethode machen würden, Format Es scheint ein schlechter Name zu sein, aber das bedeutet nicht, dass die Funktionalität keine Instanzmethode sein sollte.

Warum nicht das?Es stimmt mit überein der Rest von das .NET-Framework

"Hello {0}".ToString("Orion");

Instanzmethoden sind gut, wenn Sie ein Objekt haben, das einen bestimmten Zustand beibehält.Der Vorgang der Formatierung einer Zeichenfolge hat keinen Einfluss auf die Zeichenfolge, die Sie bearbeiten (lesen Sie:ändert seinen Zustand nicht), erstellt es eine neue Zeichenfolge.

Mit Erweiterungsmethoden können Sie jetzt Ihren Kuchen haben und ihn auch essen (d. h.Sie können die letztere Syntax verwenden, wenn Sie dadurch nachts besser schlafen können.

Ich denke, es sieht im Allgemeinen besser aus, String.Format zu verwenden, aber ich könnte einen Sinn darin sehen, eine nicht statische Funktion zu haben, wenn Sie bereits eine Zeichenfolge in einer Variablen gespeichert haben, die Sie „formatieren“ möchten.

Abgesehen davon wirken sich alle Funktionen der String-Klasse nicht auf den String aus, sondern geben ein neues String-Objekt zurück, da Strings unveränderlich sind.

@Jared:

Nicht überladene, nicht geerbte statische Methoden (wie Class.b(a,c)), die eine Instanz als erste Variable annehmen, sind semantisch äquivalent zu einem Methodenaufruf (wie a.b(c)).

Nein, das sind sie nicht.

(Vorausgesetzt, es wird mit derselben CIL kompiliert, was auch der Fall sein sollte.)

Das ist dein Fehler.Die erzeugte CIL ist unterschiedlich.Der Unterschied besteht darin, dass Mitgliedsmethoden nicht aufgerufen werden können null Werte, sodass die CIL eine Prüfung gegen diese Werte einfügt null Werte.Dies ist in der statischen Variante offensichtlich nicht der Fall.

Jedoch, String.Format tut nicht erlauben null Werte, sodass die Entwickler manuell einen Scheck einfügen mussten.Aus dieser Sicht wäre die Member-Methodenvariante technisch überlegen.

Dies dient dazu, Verwechslungen mit zu vermeiden .ToString() Methoden.

Zum Beispiel:

double test = 1.54d;

//string.Format pattern
string.Format("This is a test: {0:F1}", test );

//ToString pattern
"This is a test: " + test.ToString("F1");

Wenn Format eine Instanzmethode für einen String wäre, könnte dies zu Verwirrung führen, da die Muster unterschiedlich sind.

String.Format() ist eine Hilfsmethode zum Umwandeln mehrerer Objekte in eine formatierte Zeichenfolge.

Eine Instanzmethode für einen String führt etwas mit diesem String aus.

Natürlich könnten Sie Folgendes tun:

public static string FormatInsert( this string input, params object[] args) {
    return string.Format( input, args );
}

"Hello {0}, I have {1} things.".FormatInsert( "world", 3);

Ich weiß nicht, warum sie es getan haben, aber es spielt keine Rolle mehr:

public static class StringExtension
{
    public static string FormatWith(this string format, params object[] args)
    {
        return String.Format(format, args);
    }
}

public class SomeClass
{
    public string SomeMethod(string name)
    {
        return "Hello, {0}".FormatWith(name);
    }
}

Das läuft meiner Meinung nach viel einfacher.

Ein großes Designziel für C# bestand darin, den Übergang von C/C++ zu C# so einfach wie möglich zu gestalten.Die Verwendung der Punktsyntax für ein Zeichenfolgenliteral würde aussehen sehr Für jemanden mit nur C/C++-Hintergrund ist das seltsam, und das Formatieren von Zeichenfolgen ist etwas, was ein Entwickler wahrscheinlich am ersten Tag mit der Sprache tun wird.Deshalb glaube ich, dass sie es statisch gemacht haben, um es näher an vertrautes Terrain heranzuführen.

Ein weiterer Grund dafür String.Format ist die Ähnlichkeit zur Funktion printf von C.Es sollte C-Entwicklern den Wechsel der Sprache erleichtern.

Ich sehe nichts Falsches daran, dass es statisch ist.

Die Semantik der statischen Methode scheint mir viel sinnvoller zu sein.Vielleicht liegt es daran, dass es sich um ein Primitiv handelt.Wo Primitive häufig verwendet werden, möchten Sie den Dienstprogrammcode für die Arbeit mit ihnen so einfach wie möglich gestalten.Außerdem denke ich, dass die Semantik viel besser ist String.Format über „MyString BLAH BLAH {0}“.Format ...

Nicht überladene, nicht geerbte statische Methoden (wie Class.b(a,c)), die eine Instanz als erste Variable annehmen, sind semantisch äquivalent zu einem Methodenaufruf (wie a.b(c)), daher hat das Plattformteam eine willkürliche, ästhetische Wahl.(Angenommen, es wird mit derselben CIL kompiliert, was auch der Fall sein sollte.) Die einzige Möglichkeit, dies herauszufinden, besteht darin, sie nach dem Grund zu fragen.

Möglicherweise taten sie dies, um die beiden Saiten lexigraphisch nahe beieinander zu halten, d. h.

String.Format("Foo {0}", "Bar");

anstatt

"Foo {0}".Format("bar");

Sie möchten wissen, worauf die Indizes abgebildet sind.Vielleicht dachten sie, dass der „.Format“-Teil nur Rauschen in der Mitte hinzufügt.

Interessanterweise ist die ToString-Methode (zumindest für Zahlen) das Gegenteil:number.ToString("000") mit der Formatzeichenfolge auf der rechten Seite.

Ich habe es noch nicht ausprobiert, aber Sie könnten eine Erweiterungsmethode für das erstellen, was Sie möchten.Ich würde es nicht tun, aber ich denke, es würde funktionieren.

Finde ich auch String.Format() eher im Einklang mit anderen gemusterten statischen Methoden wie Int32.Parse(), long.TryParse(), usw.

Sie nutzen auch einfach eine Cloud StringBuilder wenn Sie ein nicht statisches Format wünschen.StringBuilder.AppendFormat()

String.Format muss eine statische Methode sein, da Zeichenfolgen unveränderlich sind. Wenn Sie es zu einer Instanzmethode machen, können Sie damit den Wert einer vorhandenen Zeichenfolge „formatieren“ oder ändern.Dies ist nicht möglich, und es würde keinen Sinn machen, daraus eine Instanzmethode zu machen, die einen neuen String zurückgibt.Daher handelt es sich um eine statische Methode.

String.Format Nimmt mindestens einen String und gibt einen anderen String zurück.Die Formatzeichenfolge muss nicht geändert werden, um eine andere Zeichenfolge zurückzugeben. Daher macht es wenig Sinn, dies zu tun (die Formatierung zu ignorieren).Andererseits wäre es auch kein allzu großer Aufwand String.Format eine Member-Funktion sein, außer ich glaube nicht, dass C# konstante Member-Funktionen zulässt, wie dies in C++ der Fall ist.[Bitte korrigieren Sie mich und diesen Beitrag, wenn dies der Fall ist.]

.NET-Strings sind unveränderlich

Daher macht es absolut keinen Sinn, eine Instanzmethode zu haben.

String foo = new String();

foo.Format("test {0}",1); // Makes it look like foo should be modified by the Format method. 

string newFoo = String.Format(foo, 1); // Indicates that a new string will be returned, and foo will be unaltered.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top