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?

Foi útil?

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:

  1. para loop
  2. loop foreach
  3. 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();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top