Un buon modo per concatenare rappresentazioni di stringhe di oggetti?
-
06-07-2019 - |
Domanda
Ok,
Abbiamo molte dove clausole nel nostro codice. Abbiamo altrettanti modi per generare una stringa per rappresentare la condizione in . Sto cercando di trovare un modo pulito come segue:
public static string Join<T>(this IEnumerable<T> items, string separator)
{
var strings = from item in items select item.ToString();
return string.Join(separator, strings.ToArray());
}
può essere usato come segue:
var values = new []{1, 2, 3, 4, 5, 6};
values.StringJoin(",");
// result should be:
// "1,2,3,4,5,6"
Quindi questo è un bel metodo di estensione che fa un lavoro molto semplice. So che il semplice codice non si trasforma sempre in un'esecuzione rapida o efficiente, ma sono solo curioso di sapere cosa avrei potuto perdere con questo semplice codice. Altri membri del nostro team sostengono che:
- non è abbastanza flessibile (nessun controllo sulla rappresentazione della stringa)
- potrebbe non essere efficiente in termini di memoria
- potrebbe non essere veloce
Qualunque esperto su cui intervenire?
Saluti,
Eric.
Soluzione
Per quanto riguarda il primo problema, è possibile aggiungere un altro parametro "formatter" per controllare la conversione di ciascun elemento in una stringa:
public static string Join<T>(this IEnumerable<T> items, string separator)
{
return items.Join(separator, i => i.ToString());
}
public static string Join<T>(this IEnumerable<T> items, string separator, Func<T, string> formatter)
{
return String.Join(separator, items.Select(i => formatter(i)).ToArray());
}
Per quanto riguarda i secondi due problemi, non mi preoccuperei a meno che in seguito non si verifichino problemi di prestazioni e non si ritenga che sia un problema. Tuttavia, è improbabile che si verifichi un grosso collo di bottiglia ...
Altri suggerimenti
Per qualche ragione, ho pensato che String.Join
fosse implementato in termini di una classe StringBuilder
. In caso contrario, è probabile che quanto segue funzioni meglio per input di grandi dimensioni poiché non ricrea un oggetto String
per ogni join nell'iterazione.
public static string Join<T>(this IEnumerable<T> items, string separator)
{
// TODO: check for null arguments.
StringBuilder builder = new StringBuilder();
foreach(T t in items)
{
builder.Append(t.ToString()).Append(separator);
}
builder.Length -= separator.Length;
return builder.ToString();
}
MODIFICA : ecco un'analisi di quando è opportuno utilizzare StringBuilder
e String.Join
.
Perché non usi StringBuilder e esegui l'iterazione della raccolta, aggiungendo. Altrimenti stai creando un array di stringhe (var string) e quindi eseguendo il join.
Mancano controlli null per la sequenza e gli elementi della sequenza. E sì, non è il modo più veloce ed efficiente in termini di memoria. Probabilmente si dovrebbe semplicemente enumerare la sequenza e rendere le rappresentazioni di stringa degli elementi in un StringBuilder
. Ma importa davvero? Stai riscontrando problemi di prestazioni? Devi ottimizzare?
funzionerebbe anche:
public static string Test(IEnumerable<T> items, string separator)
{
var builder = new StringBuilder();
bool appendSeperator = false;
if(null != items)
{
foreach(var item in items)
{
if(appendSeperator)
{
builder.Append(separator)
}
builder.Append(item.ToString());
appendSeperator = true;
}
}
return builder.ToString();
}