Come troncare una stringa .NET?


406

Vorrei troncare una stringa in modo tale che la sua lunghezza non sia più lunga di un dato valore. Sto scrivendo su una tabella di database e voglio assicurarmi che i valori che scrivo soddisfino il vincolo del tipo di dati della colonna.

Ad esempio, sarebbe bello se potessi scrivere quanto segue:

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

Sfortunatamente, questo solleva un'eccezione perché maxLengthgeneralmente supera i limiti della stringa value. Certo, potrei scrivere una funzione come la seguente, ma speravo che qualcosa del genere esistesse già.

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
} 

Dov'è l'API sfuggente che esegue questa attività? Ce n'è uno?


24
Per la cronaca, le stringhe sono immutabili, non puoi troncarle, puoi solo restituirne una copia troncata. Nitpicky, lo so.
John Weldon,

2
@ John Weldon: Questo è probabilmente il motivo per cui la funzione membro non esiste - non segue la semantica del tipo di dati. In una nota StringBuildera margine , ti consente di troncare stringendo la lunghezza, ma devi comunque eseguire il controllo della lunghezza per evitare di allargare la corda.
Steve Guidi,

1
Qualunque soluzione tu scelga, assicurati di aggiungere un segno di spunta per una stringa nulla prima di chiamare Sottostringa o accedere alla proprietà Lunghezza.
Ray,

3
@SteveGuidi - Se così fosse, allora non ci sarebbero funzioni come Trim o Replace, che affrontano problemi semantici simili
Chris Rogers,

1
@JohnWeldon Sempre più nitidi di Microsoft stessi sono, come succede, sono felici di documentare, ad esempio, .Trim()in un modo che lo fa sembrare fuorviante come se muta la stringa: "Rimuove tutti i caratteri iniziali e finali dello spazio bianco dal oggetto String corrente. "
Mark Amery,

Risposte:


620

Truncate()Purtroppo non esiste un metodo sulla stringa. Devi scrivere questo tipo di logica tu stesso. Quello che puoi fare, tuttavia, è racchiuderlo in un metodo di estensione in modo da non doverlo duplicare ovunque:

public static class StringExt
{
    public static string Truncate(this string value, int maxLength)
    {
        if (string.IsNullOrEmpty(value)) return value;
        return value.Length <= maxLength ? value : value.Substring(0, maxLength); 
    }
}

Ora possiamo scrivere:

var someString = "...";
someString = someString.Truncate(2);

5
Ottima soluzione, ma ricordato che funziona solo in NET 3.5 e versioni successive. Non provarlo in NET2.0.
Jedi Master Spooky,

7
Finché sei in VS 2008 e presumibilmente VS 2010, puoi comunque farlo anche se hai come target .Net 2.0. danielmoth.com/Blog/…
Segna

4
Questo fallirà quando maxLengthè un valore negativo.
Bernard,

42
@ Bernard, questo dovrebbe fallire se maxLength è negativo. Qualsiasi altro comportamento sarebbe inaspettato.
Bojingo,

12
È possibile chiamare i metodi di estensione su valori null.
Joel Malone,

127

O invece dell'operatore ternario, puoi usare Math.min

public static class StringExt
{
    public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}

10
Intelligente! E la seguente espressione è ottimizzato per restituire un riferimento alla stringa originale: value.Substring(0, value.Length).
Steve Guidi,

4
Sfortunatamente non è ottimizzato per i casi in cui value.Length è inferiore a MaxLength che può essere un caso comune in alcuni dati. Anche la proprietà Lunghezza su stringa deve essere maiuscola.
jpierson,

1
Questo fallirà quando maxLengthè un valore negativo.
Bernard,

7
@Bernard, così faranno molte cose nel framework ... ma se lo cerco ... o devo impostare maxLengthdi default su 0oppure value.Length; o ho bisogno di lanciare un ArgumentOutOfRangeException... che ha più senso in questo caso, ed è già lanciato da Substringcomunque.
CaffGeek,

2
Un po 'più breve:return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
user1127860,

43

Ho pensato di lanciare la mia implementazione poiché credo che copra tutti i casi che sono stati toccati dagli altri e lo fa in un modo conciso che è ancora leggibile.

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

Questa soluzione si basa principalmente sulla soluzione di Ray e apre il metodo da utilizzare come metodo di estensione usando questa parola chiave proprio come fa LBushkin nella sua soluzione.


Questo fallirà quando maxLengthè un valore negativo.
Bernard,

15
@Bernard - Consiglierei di non passare un valore negativo per l'argomento maxLength in quanto è un valore imprevisto. Il metodo Substring utilizza lo stesso approccio, quindi non c'è motivo di migliorare l'eccezione che genera.
jpierson,

Non credo sia necessario il controllo IsNullOrEmpty? (1) Se il valore è nullo, non dovrebbe esserci modo di chiamare questo metodo di estensione su di esso. (2) Se value è la stringa vuota, il controllo value.Length> maxLength fallirà.
Jon Schneider,

8
@JonSchneider, IsNullOrEmpty è necessario perché si tratta di un metodo di estensione. Se si dispone di una variabile di tipo stringa a cui è stato assegnato un valore null, il compilatore non inserisce un controllo null prima di chiamare questo metodo. Tecnicamente, questo è ancora un metodo statico della classe statica. Quindi: stringVar.Truncate (2) Compila come: StringExt.Truncate (stringVar, 2);
Jeff B,

40

Perché il test delle prestazioni è divertente: (usando i metodi di estensione linqpad )

var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));

foreach(var limit in new[] { 10, 25, 44, 64 })
    new Perf<string> {
        { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
        { "concat" + limit, n => string.Concat(val.Take(limit)) },
        { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
        { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
        { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
    }.Vs();

Il truncatemetodo è stato "significativamente" più veloce. #microoptimization

presto

  • truncate10 5788 tick scaduti (0,5788 ms) [in 10K ripetizioni, 5,788E-05 ms per]
  • smart-trunc10 8206 tick scaduti (0,8206 ms) [in 10K ripetizioni, 8,206E-05 ms per]
  • stringbuilder10 10557 tick scaduti (1.0557 ms) [in 10K ripetizioni, 0,00010557 ms per]
  • concat10 45495 tick scaduti (4.5495 ms) [in 10K ripetizioni, 0.00045495 ms per]
  • newstring10 72535 tick scaduti (7,2535 ms) [in 10K ripetizioni, 0,00072535 ms per]

in ritardo

  • truncate44 8835 tick scaduti (0,8835 ms) [in 10K ripetizioni, 8,835 E-05 ms per]
  • stringbuilder44 13106 tick scaduti (1.3106 ms) [in 10K ripetizioni, 0,00013106 ms per]
  • smart-trunc44 14821 tick scaduti (1.4821 ms) [in ripetizioni da 10K, 0,00014821 ms per]
  • newstring44 144324 tick scaduti (14.4324 ms) [in 10K ripetizioni, 0,00144324 ms per]
  • concat44 174610 tick scaduti (17.461 ms) [in 10K ripetizioni, 0,0017461 ms per]

Troppo lungo

  • smart-trunc64 6944 tick scaduti (0,6944 ms) [in 10K ripetizioni, 6,944E-05 ms per]
  • truncate64 7686 tick scaduti (0,7686 ms) [in 10K ripetizioni, 7,686E-05 ms per]
  • stringbuilder64 13314 tick trascorsi (1.3314 ms) [in 10K ripetizioni, 0,00013314 ms per]
  • newstring64 177481 tick scaduti (17.7481 ms) [in 10K ripetizioni, 0,00177481 ms per]
  • concat64 241601 tick scaduti (24.1601 ms) [in 10K ripetizioni, 0,00241601 ms per]

Grazie per tutti i benchmark utili! ... e Linkpad spacca!
Sunsetquest,

non importava che linqpad potesse fare quelle cose
jefissu,

38

In .NET 4.0 è possibile utilizzare il Takemetodo:

string.Concat(myString.Take(maxLength));

Non testato per l'efficienza!


27

Puoi usare LINQ ... elimina la necessità di controllare la lunghezza della stringa. Certo, forse non è il più efficiente, ma è divertente.

string result = string.Join("", value.Take(maxLength)); // .NET 4 Join

o

string result = new string(value.Take(maxLength).ToArray());

2
perché questa non è la risposta accettata? Cosa c'è di più semplice, scrivere il proprio metodo di estensione che è necessario mantenere / documentare o usare qualcosa di INCORPORATO come. Prendere
Don Cheadle

9
@mmcrae Linq potrebbe essere più semplice, ma è anche molto più lento. Il mio benchmark dice ~ 400ms per Linq e solo ~ 24ms per Substring per 1 milione di iterazioni.
Hein Andre Grønnestad,

Questa soluzione non dovrebbe mai essere utilizzata. Come detto in due commenti sopra, c'è sempre allocazione di memoria, anche quando la stringa esistente non è maggiore della lunghezza massima. Inoltre è molto lento.
Kamarey,

15

Ho fatto il mio in una riga in questo modo

value = value.Length > 1000 ? value.Substring(0, 1000) : value;

2
-1; questo non aggiunge nulla che non fosse già nella risposta accettata.
Mark Amery,

2
@markamery è un'alternativa più breve con meno codice per scrivere e aggiornare quando è necessario utilizzarlo. Non ti piace? Non usarlo
SeanMC

Veloce, semplice e veloce. Questo è quello di cui avevo bisogno. Grazie!
Peter,

14

Sembra che nessuno abbia ancora pubblicato questo:

public static class StringExt
{
    public static string Truncate(this string s, int maxLength)
    {
        return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
    }
}

L'uso dell'operatore && lo rende leggermente migliore della risposta accettata.


13

.NET Framework ha un'API per troncare una stringa come questa:

Microsoft.VisualBasic.Strings.Left(string, int);

Ma in un'app C # probabilmente preferirai eseguire il rollup del tuo rispetto a prendere una dipendenza da Microsoft.VisualBasic.dll, la cui principale ragion d'essere è la retrocompatibilità.


".NET Framework ha un'API" ti stai contraddicendo. Questa è un'API VB.NET
Camilo Terevinto il

9
@CamiloTerevinto: è un'API fornita con .NET Framework e può essere chiamata da qualsiasi lingua gestita.
Joe,

1
La DLL VB contiene molte cose buone. Perché ci sono così tanti sviluppatori c # contro di esso?
Michael Z.

Nessun supporto .NET Core attualmente, purtroppo. In effetti, gli interi Microsoft.VisualBasic.Stringsmoduli in .NET Core sono piuttosto vuoti .
Mark Amery,

1
Mentre sono d'accordo con il commento di Joe, non mi sento ancora giusto chiamare qualcosa di specifico per VB da altre lingue. Se ci sono così tante cose buone in "VB DLL", perché non metterle in un posto condiviso? Chissà cosa farà domani Microsoft con queste cose? Interrompere il supporto o qualcosa del genere ..
Kamarey,


6

So che questa è una vecchia domanda, ma ecco una bella soluzione:

public static string Truncate(this string text, int maxLength, string suffix = "...")
{
    string str = text;
    if (maxLength > 0)
    {
        int length = maxLength - suffix.Length;
        if (length <= 0)
        {
            return str;
        }
        if ((text != null) && (text.Length > maxLength))
        {
            return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
        }
    }
    return str;
}

var myString = "hello world"
var myTruncatedString = myString.Truncate(4);

Ritorni: ciao ...


@SarjanWebDev Quel personaggio speciale appare come "." in cmd.exe
Neal Ehardt,

5

Una variante simile con l'operatore di propagazione Null di C # 6

public static string Truncate(this string value, int maxLength)
{
    return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}

Si prega di notare, essenzialmente stiamo verificando se valueè null due volte qui.


5

Ancora nessun metodo Truncate nel 2016 per le stringhe C #. Ma - Usando la sintassi di C # 6.0:

public static class StringExtension
{
  public static string Truncate(this string s, int max) 
  { 
    return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s); 
  }
}

Esso funziona magicamente:

"Truncate me".Truncate(8);
Result: "Truncate"

4

Prendendo @CaffGeek e semplificandolo:

public static string Truncate(this string value, int maxLength)
    {
        return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
    }

4

Kndly nota che troncare una stringa non significa semplicemente tagliare una corda da sola per una lunghezza specificata, ma bisogna fare attenzione a non dividere la parola.

es. stringa: questa è una stringa di prova.

Voglio tagliarlo alle 11. Se utilizziamo uno dei metodi sopra indicati, il risultato sarà

questo è un te

Questa non è la cosa che vogliamo

Anche il metodo che sto usando potrebbe non essere così perfetto, ma può gestire la maggior parte della situazione

public string CutString(string source, int length)
{
        if (source== null || source.Length < length)
        {
            return source;
        }
        int nextSpace = source.LastIndexOf(" ", length);
        return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
} 

4

Perchè no:

string NormalizeLength(string value, int maxLength)
{
    //check String.IsNullOrEmpty(value) and act on it. 
    return value.PadRight(maxLength).Substring(0, maxLength);
}

vale a dire nel value.Length < maxLengthpad degli eventi spazi alla fine o troncare l'eccesso.


Generi il doppio di oggetti stringa e potresti generare una NullReferenceException dalla chiamata PadRight se il valore è null che non è appropriato, dovrebbe essere ArgumentNullException.
Jeremy,

1
@Jeremy Non capisco "potrebbe generare una NullReferenceException dalla chiamata PadRight se il valore è null"; non ho menzionato "// check string.IsNullOrEmpty (value) e agire su di esso."
Sri

3

Nel caso in cui non ci siano abbastanza risposte qui, ecco la mia :)

public static string Truncate(this string str, 
                              int totalLength, 
                              string truncationIndicator = "")
{
    if (string.IsNullOrEmpty(str) || str.Length < totalLength) 
        return str;

    return str.Substring(0, totalLength - truncationIndicator.Length) 
           + truncationIndicator;
}

usare:

"I use it like this".Truncate(5,"~")

2

Per motivi di (eccessiva) complessità, aggiungerò la mia versione sovraccaricata che sostituisce gli ultimi 3 caratteri con i puntini di sospensione rispetto al parametro maxLength.

public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
    if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
        throw new ArgumentOutOfRangeException("maxLength",
            "maxLength should be greater than three when replacing with an ellipsis.");

    if (String.IsNullOrWhiteSpace(value)) 
        return String.Empty;

    if (replaceTruncatedCharWithEllipsis &&
        value.Length > maxLength)
    {
        return value.Substring(0, maxLength - 3) + "...";
    }

    return value.Substring(0, Math.Min(value.Length, maxLength)); 
}

2

I miei due centesimi con lunghezza di esempio di 30:

  var truncatedInput = string.IsNullOrEmpty(input) ? 
      string.Empty : 
      input.Substring(0, Math.Min(input.Length, 30));

1

Preferisco la risposta di jpierson, ma nessuno degli esempi che vedo qui sta gestendo un parametro maxLength non valido, come quando maxLength <0.

Le scelte potrebbero essere o gestire l'errore in un tentativo / cattura, bloccare il parametro maxLength min su 0 o se maxLength è inferiore a 0 restituire una stringa vuota.

Codice non ottimizzato:

public string Truncate(this string value, int maximumLength)
{
    if (string.IsNullOrEmpty(value) == true) { return value; }
    if (maximumLen < 0) { return String.Empty; }
    if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
    return value;
}

3
Si noti che nella mia implementazione ho scelto di non gestire il caso in cui maximumLength è inferiore a 0 perché ho pensato che l'unica cosa che avrei fatto è lanciare un ArgumentOutOfRangeExcpetion che essenzialmente ciò che string.Substring () fa per me.
jpierson,

1

Ecco una soluzione vb.net, segna che l'istruzione if (sebbene brutta) migliora le prestazioni perché non abbiamo bisogno dell'istruzione di sottostringa quando stringa è già più piccola della lunghezza massima ... Rendendola un'estensione per stringa è facile da usare. ..

 <System.Runtime.CompilerServices.Extension()> _
    Public Function Truncate(String__1 As String, maxlength As Integer) As String
        If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
            Return String__1.Substring(0, maxlength)
        Else
            Return String__1
        End If
    End Function

In VB.net è possibile sostituire "Not String.IsNullOrEmpty (String__1)" con "String__1 <> Nothing". È un po 'più corto. Il valore predefinito per le stringhe è una stringa vuota. L'uso di "<> Nothing" controlla sia i casi di stringa nulli che quelli vuoti.
Provalo

In VB puoi fare Sinistra (stringa, lunghezza massima)
Michael Z.

1

So che ci sono già un sacco di risposte, ma il mio bisogno era di mantenere intatti l'inizio e la fine della stringa ma di accorciarla a una lunghezza inferiore.

    public static string TruncateMiddle(string source)
    {
        if (String.IsNullOrWhiteSpace(source) || source.Length < 260) 
            return source;

        return string.Format("{0}...{1}", 
            source.Substring(0, 235),
            source.Substring(source.Length - 20));
    }

Questo serve per creare URL di SharePoint con una lunghezza massima di 260 caratteri.

Non ho fatto della lunghezza un parametro poiché è una costante 260. Inoltre non ho fatto della lunghezza della sottostringa un parametro perché voglio che si spezzi in un punto specifico. Infine, la seconda sottostringa è la lunghezza della fonte - 20 poiché conosco la struttura delle cartelle.

Questo potrebbe essere facilmente adattato alle tue esigenze specifiche.


1

So che ci sono già un sacco di risposte qui, ma questa è quella con cui sono andato, che gestisce entrambe le stringhe null e la situazione in cui la lunghezza passata è negativa:

public static string Truncate(this string s, int length)
{
    return string.IsNullOrEmpty(s) || s.Length <= length ? s 
        : length <= 0 ? string.Empty 
        : s.Substring(0, length);
}

1

In C # 8 è possibile utilizzare la nuova funzionalità Ranges ...

value = value[..Math.Min(30, value.Length)];

0

Non c'è nulla in .net per questo di cui sono a conoscenza - ecco la mia versione che aggiunge "...":

public static string truncateString(string originalString, int length) {
  if (string.IsNullOrEmpty(originalString)) {
   return originalString;
  }
  if (originalString.Length > length) {
   return originalString.Substring(0, length) + "...";
  }
  else {
   return originalString;
  }
}

2
La tua versione fornirà stringhe di 3 caratteri più lunghe della lunghezza richiesta, nel caso vengano troncate. Inoltre, i punti tripli sono davvero significativi nella rappresentazione, non lo memorizzerei in un database come quello che è il caso d'uso fornito dall'OP.
MarioDS,

0

TruncateString

public static string _TruncateString(string input, int charaterlimit)
{
    int characterLimit = charaterlimit;
    string output = input;

    // Check if the string is longer than the allowed amount
    // otherwise do nothing
    if (output.Length > characterLimit && characterLimit > 0)
    {
        // cut the string down to the maximum number of characters
        output = output.Substring(0, characterLimit);
        // Check if the character right after the truncate point was a space
        // if not, we are in the middle of a word and need to remove the rest of it
        if (input.Substring(output.Length, 1) != " ")
        {
            int LastSpace = output.LastIndexOf(" ");

            // if we found a space then, cut back to that space
            if (LastSpace != -1)
            {
                output = output.Substring(0, LastSpace);
            }
        }
        // Finally, add the "..."
        output += "...";
    }
    return output;
}

2
Perché precedi il nome del tuo metodo pubblico con un trattino basso?
Michael Z.

0

In aggiunta alle possibilità discusse sopra, vorrei condividere la mia soluzione. È un metodo di estensione che consente null (restituisce string.Empty) e c'è anche un secondo .Truncate () per usarlo con i puntini di sospensione. Attenzione, non è ottimizzato per le prestazioni.

public static string Truncate(this string value, int maxLength) =>
    (value ?? string.Empty).Substring(0, (value?.Length ?? 0) <= (maxLength < 0 ? 0 : maxLength) ? (value?.Length ?? 0) : (maxLength < 0 ? 0 : maxLength));
public static string Truncate(this string value, int maxLength, string ellipsis) =>
    string.Concat(value.Truncate(maxLength - (((value?.Length ?? 0) > maxLength ? ellipsis : null)?.Length ?? 0)), ((value?.Length ?? 0) > maxLength ? ellipsis : null)).Truncate(maxLength);

-1
public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
    }

La ToArray()chiamata qui è solo inutile sovraccarico; usando ad es. String.Concatpuoi costruire una stringa da un enumerabile numero di caratteri senza dover passare attraverso un array.
Mark Amery,

-3

Tronca la stringa

public static string TruncateText(string strText, int intLength)
{
    if (!(string.IsNullOrEmpty(strText)))
    {                                
        // split the text.
        var words = strText.Split(' ');

        // calculate the number of words
        // based on the provided characters length 
        // use an average of 7.6 chars per word.
        int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));

        // if the text is shorter than the length,
        // display the text without changing it.
        if (words.Length <= wordLength)
            return strText.Trim();                

        // put together a shorter text
        // based on the number of words
        return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
    }
        else
        {
            return "";
        }            
    }

Ciò non risponde alla domanda del PO. Innanzitutto, dovrebbe essere una funzione membro (anche se l'hai scritta come metodo di estensione). In secondo luogo, l'OP non specifica che il testo debba essere diviso e che le parole siano state troncate a ca. 7,6 caratteri per parola.
Wicher Visser,

7.6 è solo un numero. puoi scrivere qualsiasi altro numero tu desideri. Questa era una lunghezza media della parola inglese. L'ho trovato su google. L'uso della divisione è solo un modo semplice per suddividere le parole in base allo spazio. Non penso che tu voglia visualizzare una mezza parola! Quindi, a meno che non si esegua il ciclo continuo per trovare spazio vuoto che richiederà più codice, questo è un modo semplice per troncare una stringa e visualizzare parole complete. Questo ti assicurerà che una stringa non è più lunga della lunghezza data e non avrai parole spezzate.
VT,

-4

Questo è il codice che di solito uso:

string getSubString(string value, int index, int length)
        {
            if (string.IsNullOrEmpty(value) || value.Length <= length)
            {
                return value;
            }
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = index; i < length; i++)
            {
                sb.AppendLine(value[i].ToString());
            }
            return sb.ToString();
        }

5
Si noti che concatenare le stringhe con + = è un'operazione costosa, soprattutto quando si ricostruisce carattere per carattere. Le stringhe .NET sono immutabili, il che significa che in questo caso viene creata una nuova stringa ogni volta nel tuo ciclo.
Steve Guidi,

Le stringhe @SteveGuidi non sono immutabili, si limitano a mascherarsi come immutabili. Vorrei che le stringhe fossero vere primitive immutabili in modo da poter avere stringa e stringa ?, ma purtroppo non sono primitive.
Chris Marisic,

Dici costoso come se il costo delle prestazioni è significativo, l'ho cambiato per usare stringBuilder ma trovo che con + = sia più facile vedere cosa sta succedendo, volevo solo che l'OP capisse facilmente il codice.
user3390116
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.