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.

È stato utile?

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