Console.WriteLine和通用List

时间:2008-09-09 21:19:44

标签: c# generics console list

我经常发现自己编写这样的代码:

List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
    Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();

更好的是这样的事情:

List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);

我怀疑有一些聪明的方法可以做到这一点,但我没有看到它。有人比第一块有更好的解决方案吗?

9 个答案:

答案 0 :(得分:69)

这样做:

list.ForEach(i => Console.Write("{0}\t", i));

编辑:对于已经回复的其他人 - 他希望他们都在同一条线上,并在它们之间有标签。 :)

答案 1 :(得分:18)

一种不同的方法,只是为了踢:

Console.WriteLine(string.Join("\t", list));

答案 2 :(得分:4)

如果有一段代码,你根据不要重复自己一直重复,你应该把它放在你自己的库中然后调用它。考虑到这一点,在这里获得正确答案有两个方面。第一个是调用库函数的代码的清晰度和简洁性。第二个是foreach的性能影响。

首先让我们考虑一下调用代码的清晰度和简洁性。

您可以通过多种方式进行预告:

  1. for loop
  2. foreach loop
  3. Collection.ForEach
  4. 用forea做一个foreach List.ForEach的所有方法都是最清晰和最简洁的。

    list.ForEach(i => Console.Write("{0}\t", i));
    

    所以在这个阶段它可能看起来像List.ForEach是要走的路。不过这是什么表现?确实,在这种情况下,写入控制台的时间将决定代码的性能。当我们对特定语言功能的表现有所了解时,我们当然至少应该考虑它。

    根据Duston Campbell's performance measurements of foreach,在优化代码下迭代列表的最快方法是使用for循环而不调用List.Count。

    然而for循环是一个冗长的构造。它也被视为一种非常迭代的做事方式,与目前的功能习语趋势不相符。

    那么我们可以获得简洁,清晰和性能吗?我们可以通过使用扩展方法。在理想的世界中,我们将在Console上创建一个扩展方法,该方法接受一个列表并用分隔符写入它。我们不能这样做,因为Console是一个静态类,扩展方法只适用于类的实例。相反,我们需要将扩展​​方法放在列表本身上(根据David B的建议):

    public static void WriteLine(this List<int> theList)
    {
      foreach (int i in list)
      {
        Console.Write("{0}\t", t.ToString());
      }
      Console.WriteLine();
    }
    

    此代码将在许多地方使用,因此我们应该进行以下改进:

    • 我们应该使用最快的方式来迭代集合,而不是使用foreach,这是一个带有缓存计数的for循环。
    • 目前只有List可以作为参数传递。作为库函数,我们可以通过少量的努力来概括它。
    • 使用List将我们限制为仅列表,使用IList也允许此代码也可以使用数组。
    • 由于扩展方法将在IList上,我们需要更改名称以使其更清楚我们写的内容:

    以下是函数代码的外观:

    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();
    }
    

    我们可以通过允许客户端传递分隔符来进一步改进这一点。然后,我们可以提供第二个函数,使用标准分隔符写入控制台,如下所示:

    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();
    }
    

    所以现在,鉴于我们想要一个简单,清晰的将表单写入控制台的方法,我们有一个。这是完整的源代码,包括使用库函数的演示:

    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();
            }
        }
    }
    

    =============================================== ======

    您可能认为这应该是答案的结束。然而,还有一个可以做到的概括。从fatcat的问题来看,他是否总是写入控制台并不清楚。也许在foreach中还有别的事情要做。在那种情况下,Jason Bunting的答案将给出这种普遍性。以下是他的回答:

    list.ForEach(i => Console.Write("{0}\t", i));
    

    除非我们对扩展方法进行一次改进,并添加FastForEach,否则如下所示:

    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();
        }
    

    这允许我们使用最快的迭代方法对集合中的每个元素执行任意代码。

    我们甚至可以将WriteToConsole函数更改为使用FastForEach

    public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
    {
         collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
    }
    

    所以现在整个源代码,包括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();
            }
        }
    }
    

答案 3 :(得分:3)

new List {1,3,5} .ForEach(Console.WriteLine);

答案 4 :(得分:2)

        List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
        a.ForEach(p => Console.WriteLine(p));
编辑:啊,他打败了我。

答案 5 :(得分:2)

list.ForEach(x=>Console.WriteLine(x));

答案 6 :(得分:2)

List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));

编辑:该死!花了很长时间才打开视觉工作室来测试它。

答案 7 :(得分:1)

你也可以加入:

var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));

答案 8 :(得分:0)

public static void WriteLine(this List<int> theList)
{
  foreach (int i in list)
  {
    Console.Write("{0}\t", t.ToString());
  }
  Console.WriteLine();
}

然后,稍后......

list.WriteLine();