Domanda

Confrontare

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

con

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

Perché i progettisti .Net hanno scelto un metodo statico rispetto a un metodo di istanza?Cosa ne pensi?

È stato utile?

Soluzione

In realtà non conosco la risposta, ma sospetto che abbia qualcosa a che fare con l'aspetto dell'invocazione diretta di metodi su stringhe letterali.

Se ricordo bene (in realtà non l'ho verificato perché non ho un vecchio IDE a portata di mano), le prime versioni dell'IDE C# avevano problemi a rilevare le chiamate al metodo rispetto ai valori letterali stringa in IntelliSense e questo ha un grande impatto sulla rilevabilità dell'API.Se così fosse, digitare quanto segue non ti darebbe alcun aiuto:

"{0}".Format(12);

Se fossi costretto a digitare

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

Sarebbe chiaro che non vi fosse alcun vantaggio nel rendere il metodo Format un metodo di istanza piuttosto che un metodo statico.

Le librerie .NET sono state progettate da molte delle stesse persone che ci hanno fornito MFC e la classe String in particolare ha una forte somiglianza con la classe CString in MFC.MFC dispone di un metodo Format di istanza (che utilizza codici di formattazione in stile printf anziché lo stile di parentesi graffe di .NET) che è doloroso perché non esiste un valore letterale CString.Quindi in una codebase MFC su cui ho lavorato vedo molto di questo:

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

il che è doloroso.(Non sto dicendo che il codice sopra sia un ottimo modo per fare cose anche in MFC, ma sembra essere il modo in cui la maggior parte degli sviluppatori del progetto ha imparato a usare CString::Format).Venendo da quella tradizione, posso immaginare che i progettisti dell'API stessero cercando di evitare di nuovo quel tipo di situazione.

Altri suggerimenti

Perché il metodo Format non ha nulla a che fare con il valore corrente di una stringa.

Questo è vero per Tutto metodi string perché le stringhe .NET sono immutabili.

Se non fosse statico, avresti bisogno di una stringa per cominciare.

Fa:la stringa di formato.

Credo che questo sia solo un altro esempio dei numerosi difetti di progettazione della piattaforma .NET (e non lo intendo come una fiamma;Trovo ancora che .NET Framework sia superiore alla maggior parte degli altri framework).

Beh, immagino che tu debba essere piuttosto particolare al riguardo, ma come dicono le persone, ha più senso che String.Format sia statico a causa della semantica implicita.Prendere in considerazione:

"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.

La prima cosa che ho fatto quando ho dovuto aggiornare a VS2008 e C#3 è stata fare questo

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

Quindi ora posso cambiare il mio codice da

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

A

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

che all'epoca preferivo.Al giorno d'oggi (2014) non mi preoccupo perché è solo un'altra seccatura continuare ad aggiungerlo a ogni progetto casuale che creo o collegarlo a qualche libreria bag-of-utils.

E perché i progettisti .NET lo hanno scelto?Chi lo sa.Sembra del tutto soggettivo.I miei soldi sono su entrambi

  • Copia di Java
  • Al ragazzo che lo scrisse in quel momento soggettivamente piacque di più.

Non ci sono davvero altri motivi validi che riesco a trovare

Penso che sia perché Format non accetta una stringa di per sé, ma una "stringa di formato".La maggior parte delle stringhe sono uguali a cose come "Bob Smith" o "1010 Main St" o cosa hai e non a "Hello {0}", generalmente inserisci quelle stringhe di formato solo quando provi a utilizzare un modello per crearne un altro string, come un metodo factory, e quindi si presta ad un metodo statico.

Penso che sia perché è un metodo creatore (non sono sicuro che ci sia un nome migliore).Tutto ciò che fa è prendere ciò che gli dai e restituire un singolo oggetto stringa.Non opera su un oggetto esistente.Se non fosse statico, avresti bisogno di una stringa per cominciare.

Perché il metodo Format non ha nulla a che fare con il valore corrente di una stringa.Il valore della stringa non viene utilizzato.Prende una stringa e ne restituisce una.

Forse i progettisti .NET hanno fatto in questo modo perché JAVA ha fatto in questo modo...

Abbraccia ed estendi.:)

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

Le stringhe .NET sono immutabili
Pertanto avere un metodo di istanza non ha assolutamente senso.

Secondo questa logica la classe string non dovrebbe avere metodi di istanza che restituiscano copie modificate dell'oggetto, eppure lo ha abbondanza (Trim, ToUpper e così via).Inoltre, anche molti altri oggetti nel framework fanno lo stesso.

Sono d'accordo che se dovessero renderlo un metodo di istanza, Format sembra che sarebbe un brutto nome, ma ciò non significa che la funzionalità non dovrebbe essere un metodo di istanza.

Perché non questo?È coerente con il resto di il framework .NET

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

I metodi di istanza sono utili quando hai un oggetto che mantiene uno stato;il processo di formattazione di una stringa non influisce sulla stringa su cui stai operando (leggi:non modifica il suo stato), crea una nuova stringa.

Con i metodi di estensione, ora puoi avere la tua torta e anche mangiarla (ad es.puoi usare quest'ultima sintassi se ti aiuta a dormire meglio la notte).

Penso che in generale sia meglio usare String.Format, ma potrei vedere un punto nel voler avere una funzione non statica per quando hai già una stringa memorizzata in una variabile che vuoi "formattare".

Per inciso, tutte le funzioni della classe string non agiscono sulla stringa, ma restituiscono un nuovo oggetto stringa, poiché le stringhe sono immutabili.

@Jared:

I metodi statici non sovraccaricati e non ereditati (come Class.b(a,c)) che accettano un'istanza come prima variabile sono semanticamente equivalenti a una chiamata al metodo (come a.b(c))

No, non lo sono.

(Supponendo che venga compilato nello stesso CIL, come dovrebbe.)

Questo è il tuo errore.Il CIL prodotto è diverso.La distinzione è che i metodi membro non possono essere invocati null valori in modo che il CIL inserisca un controllo contro null valori.Questo ovviamente non viene fatto nella variante statica.

Tuttavia, String.Format fa non permettere null valori quindi gli sviluppatori hanno dovuto inserire un controllo manualmente.Da questo punto di vista la variante del metodo membro sarebbe tecnicamente superiore.

Questo per evitare confusione con .ToString() metodi.

Ad esempio:

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");

Se Format fosse un metodo di istanza su stringa ciò potrebbe causare confusione, poiché i modelli sono diversi.

String.Format() è un metodo di utilità per trasformare più oggetti in una stringa formattata.

Un metodo di istanza su una stringa fa qualcosa su quella stringa.

Certo, potresti fare:

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

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

Non so perché lo abbiano fatto, ma non ha più molta importanza:

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);
    }
}

Scorre molto più facilmente, IMHO.

Un grande obiettivo di progettazione per C# era rendere la transizione da C/C++ il più semplice possibile.L'uso della sintassi del punto su una stringa letterale sembrerebbe molto strano per qualcuno con solo un background C/C++, e la formattazione delle stringhe è qualcosa che uno sviluppatore probabilmente farà il primo giorno con il linguaggio.Quindi credo che lo abbiano reso statico per renderlo più vicino al territorio familiare.

Un altro motivo per String.Format è la somiglianza con la funzione printf da C.Avrebbe dovuto consentire agli sviluppatori C di passare più facilmente le lingue.

Non ci vedo niente di sbagliato nel fatto che sia statico..

La semantica del metodo statico mi sembra avere molto più senso.Forse è perché è un primitivo.Laddove si utilizzano spesso le primitive, è necessario rendere il codice di utilità per lavorare con esse il più leggero possibile.Inoltre, penso che la semantica sia molto migliore con String.Format Sopra "MyString BLAH BLAH {0}".Format ...

I metodi statici non sovraccaricati e non ereditati (come Class.b(a,c)) che accettano un'istanza come prima variabile sono semanticamente equivalenti a una chiamata al metodo (come a.b(c)), quindi il team della piattaforma ha creato un metodo arbitrario, scelta estetica.(Supponendo che venga compilato nello stesso CIL, come dovrebbe.) L'unico modo per saperlo sarebbe chiedere loro perché.

Forse lo fecero per mantenere le due stringhe vicine l'una all'altra lessigraficamente, cioè

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

invece di

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

Vuoi sapere su cosa sono mappati gli indici;forse pensavano che la parte ".Format" aggiungesse solo rumore nel mezzo.

È interessante notare che il metodo ToString (almeno per i numeri) è l'opposto:number.ToString("000") con la stringa di formato sul lato destro.

Non l'ho ancora provato ma potresti creare un metodo di estensione per quello che desideri.Non lo farei, ma penso che funzionerebbe.

Inoltre trovo String.Format() più in linea con altri metodi statici modellati come Int32.Parse(), long.TryParse(), eccetera.

Anche il cloud utilizza semplicemente a StringBuilder se vuoi un formato non statico.StringBuilder.AppendFormat()

String.Format deve essere un metodo statico perché le stringhe sono immutabili. Renderlo un metodo di istanza implicherebbe che potresti usarlo per "formattare" o modificare il valore di una stringa esistente.Questo non puoi farlo e renderlo un metodo di istanza che restituisca una nuova stringa non avrebbe senso.Quindi è un metodo statico.

String.Format prende almeno una stringa e restituisce una stringa diversa.Non è necessario modificare la stringa di formato per restituire un'altra stringa, quindi non ha molto senso farlo (ignorando la sua formattazione).D'altro canto non sarebbe poi così complicato realizzarlo String.Format essere una funzione membro, tranne per il fatto che non penso che C# consenta funzioni membro const come fa C++.[Per favore, correggi me e questo post se lo fa.]

Le stringhe .NET sono immutabili

Pertanto avere un metodo di istanza non ha assolutamente senso.

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.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top