Console.WriteLine e genérico Lista
Pergunta
Eu freqüentemente me encontro a escrever código como este:
List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();
Melhor seria algo como isto:
List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);
Eu suspeito que há alguma maneira inteligente de fazer isso, mas eu não consigo vê-lo.Alguém tem uma solução melhor do que o primeiro bloco?
Solução
Fazer isso:
list.ForEach(i => Console.Write("{0}\t", i));
EDITAR:Para os outros que responderam - ele quer todos eles na mesma linha, com separadores entre eles.:)
Outras dicas
Uma abordagem diferente, apenas por diversão:
Console.WriteLine(string.Join("\t", list));
Se houver um pedaço de código que você repita todo o tempo, de acordo com não Repita você Mesmo, você deve colocá-lo na sua própria biblioteca e chamada.Com isso em mente, há 2 aspectos para obter o direito de resposta aqui.A primeira é a clareza e concisão no código que chama a função de biblioteca.O segundo é o desempenho implicações do foreach.
Primeiro vamos pensar sobre a clareza e concisão no código de chamada.
Você pode fazer foreach em um número de maneiras:
- para loop
- loop foreach
- Coleção.ForEach
De todas as formas fazer um foreach na Lista.ForEach com um lambda é a mais clara e breve.
list.ForEach(i => Console.Write("{0}\t", i));
Assim, nesta fase pode parecer a Lista.ForEach é o caminho a percorrer.No entanto, qual é o desempenho desta?É verdade que, neste caso, o tempo para escrever para o console irá reger o desempenho do código.Quando sabemos algo sobre o desempenho de um idioma específico, característica que certamente deve, pelo menos, considerá-lo.
De acordo com a Duston Campbell medições de desempenho do foreach a forma mais rápida de iterar a lista em optimizado código está usando um loop for, sem uma chamada para a Lista.Contagem.
O loop for é, entretanto, um detalhado construir.É também vista como um iterativa maneira de fazer as coisas que não coincide com a tendência atual em direção funcional de expressões idiomáticas.
Então, podemos obter brevidade, clareza e desempenho?Podemos, usando um método de extensão.Em um mundo ideal seria criar um método de extensão no Console, que leva de uma lista e a escreve-lo com um delimitador.Nós não podemos fazer isso porque o Console é uma classe estática e métodos de extensão só funciona em instâncias de classes.Em vez disso, precisamos colocar o método de extensão na lista em si (como por David B de sugestão):
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
Esse código vai usados em muitos lugares, por isso, devemos realizar as seguintes melhorias:
- Em vez de usar o foreach, devemos usar a forma mais rápida de iteração de coleção que é um loop for com um contador em cache.
- Atualmente só Lista pode ser passado como um argumento.Como uma biblioteca de função podemos generalizar através de uma pequena quantidade de esforço.
- Usando a Lista de limites de nós, Listas, Usando IList permite que esse código para trabalhar com Matrizes muito.
- Desde o método de extensão estará em uma IList precisamos mudar o nome para torná-lo mais claro o que estamos a escrever para:
Veja como o código para a função ficaria:
public static void WriteToConsole<T>(this IList<T> collection)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}\t", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
Podemos melhorar isso ainda mais, permitindo que o cliente passar o delimitador.Poderíamos, então, fornecer uma segunda função que escreve para o console com o delimitador padrão como esse:
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
Então, agora, o dado que queremos uma breve e clara a performance maneira de escrever listas para o console de nós tem um.Aqui está todo o código-fonte, incluindo uma demonstração de usar a biblioteca de função:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
int count = collection.Count();
for(int i = 0; i < count; ++i)
{
Console.Write("{0}{1}", collection[i].ToString(), delimiter);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
Console.Read();
}
}
}
=======================================================
Você pode pensar que este deve ser o fim da resposta.No entanto, há mais uma peça de generalização que pode ser feito.Não está claro a partir de líder pergunta se ele está sempre de escrever para o console.Talvez algo mais deve ser feito na foreach.Nesse caso, Jason Cia resposta do vai dar que a generalidade.Aqui está a sua resposta novamente:
list.ForEach(i => Console.Write("{0}\t", i));
Que é menos que um mais requinte aos seus métodos de extensão e adicionar FastForEach como abaixo:
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
Isto nos permite executar qualquer código arbitrário em relação a cada elemento na coleção usando o mais rápido possível método de iteração.
Podemos até mesmo mudar o WriteToConsole função para usar FastForEach
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
Então, agora, todo o código-fonte, incluindo um exemplo de uso do FastForEach é:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleWritelineTest
{
public static class Extensions
{
public static void WriteToConsole<T>(this IList<T> collection)
{
WriteToConsole<T>(collection, "\t");
}
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
public static void FastForEach<T>(this IList<T> collection, Action<T> actionToPerform)
{
int count = collection.Count();
for (int i = 0; i < count; ++i)
{
actionToPerform(collection[i]);
}
Console.WriteLine();
}
}
internal class Foo
{
override public string ToString()
{
return "FooClass";
}
}
internal class Program
{
static void Main(string[] args)
{
var myIntList = new List<int> {1, 2, 3, 4, 5};
var myDoubleList = new List<double> {1.1, 2.2, 3.3, 4.4};
var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6};
var myFooList = new List<Foo> {new Foo(), new Foo(), new Foo()};
// Using the standard delimiter /t
myIntList.WriteToConsole();
myDoubleList.WriteToConsole();
myDoubleArray.WriteToConsole();
myFooList.WriteToConsole();
// Using our own delimiter ~
myIntList.WriteToConsole("~");
// What if we want to write them to separate lines?
myIntList.FastForEach(item => Console.WriteLine(item.ToString()));
Console.Read();
}
}
}
nova Lista { 1, 3, 5 }.ForEach(Console.WriteLine);
List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
a.ForEach(p => Console.WriteLine(p));
editar:ahhh ele me batia para ele.
list.ForEach(x=>Console.WriteLine(x));
List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));
Editar:Caramba!demorou muito para abrir o visual studio para testá-lo.
Você também pode fazer juntar-se:
var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
Em seguida, mais tarde...
list.WriteLine();