Juste utiliser
string.Join(",", yourCollection)
De cette façon, vous n'avez pas besoin de StringBuilder
la boucle et.
Ajout long sur le cas asynchrone. À partir de 2019, ce n'est pas une configuration rare lorsque les données arrivent de manière asynchrone.
Dans le cas où vos données sont dans une collection asynchrone, il n'y a pas de string.Join
prise de surcharge IAsyncEnumerable<T>
. Mais il est facile d'en créer un manuellement, en piratant le code à partir destring.Join
:
public static class StringEx
{
public static async Task<string> JoinAsync<T>(string separator, IAsyncEnumerable<T> seq)
{
if (seq == null)
throw new ArgumentNullException(nameof(seq));
await using (var en = seq.GetAsyncEnumerator())
{
if (!await en.MoveNextAsync())
return string.Empty;
string firstString = en.Current?.ToString();
if (!await en.MoveNextAsync())
return firstString ?? string.Empty;
// Null separator and values are handled by the StringBuilder
var sb = new StringBuilder(256);
sb.Append(firstString);
do
{
var currentValue = en.Current;
sb.Append(separator);
if (currentValue != null)
sb.Append(currentValue);
}
while (await en.MoveNextAsync());
return sb.ToString();
}
}
}
Si les données arrivent de manière asynchrone mais que l'interface IAsyncEnumerable<T>
n'est pas prise en charge (comme mentionné dans les commentaires SqlDataReader
), il est relativement facile d'encapsuler les données dans un IAsyncEnumerable<T>
:
async IAsyncEnumerable<(object first, object second, object product)> ExtractData(
SqlDataReader reader)
{
while (await reader.ReadAsync())
yield return (reader[0], reader[1], reader[2]);
}
et utilisez-le:
Task<string> Stringify(SqlDataReader reader) =>
StringEx.JoinAsync(
", ",
ExtractData(reader).Select(x => $"{x.first} * {x.second} = {x.product}"));
Pour l'utiliser Select
, vous devrez utiliser le package nuget System.Interactive.Async
. Ici vous pouvez trouver un exemple compilable.
string.Join(",", yourCollection)
? Edit: ajouté comme réponse.