C# Console.WriteLine 和通用列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Console.WriteLine and generic List
提问by Justin R.
I frequently find myself writing code like this:
我经常发现自己在写这样的代码:
List<int> list = new List<int> { 1, 3, 5 };
foreach (int i in list) {
Console.Write("{0}\t", i.ToString()); }
Console.WriteLine();
Better would be something like this:
最好是这样的:
List<int> list = new List<int> { 1, 3, 5 };
Console.WriteLine("{0}\t", list);
I suspect there's some clever way of doing this, but I don't see it. Does anybody have a better solution than the first block?
我怀疑有一些聪明的方法可以做到这一点,但我没有看到。有人有比第一个块更好的解决方案吗?
采纳答案by Jason Bunting
Do this:
做这个:
list.ForEach(i => Console.Write("{0}\t", i));
EDIT: To others that have responded - he wants them all on the same line, with tabs between them. :)
编辑:对于已经做出回应的其他人 - 他希望他们都在同一行上,在他们之间有标签。:)
回答by John Boker
List<int> a = new List<int>() { 1, 2, 3, 4, 5 };
a.ForEach(p => Console.WriteLine(p));
edit: ahhh he beat me to it.
编辑:啊哈,他打败了我。
回答by Mark Cidade
list.ForEach(x=>Console.WriteLine(x));
回答by George Mauer
List<int> list = new List<int> { 1, 3, 5 };
list.ForEach(x => Console.WriteLine(x));
Edit: Dammit! took too long to open visual studio to test it.
编辑:该死!花了太长时间打开visual studio来测试它。
回答by Vinko Vrsalovic
A different approach, just for kicks:
一种不同的方法,只是为了踢:
Console.WriteLine(string.Join("\t", list));
回答by Amy B
public static void WriteLine(this List<int> theList)
{
foreach (int i in list)
{
Console.Write("{0}\t", t.ToString());
}
Console.WriteLine();
}
Then, later...
然后,后来...
list.WriteLine();
回答by Amy B
new List { 1, 3, 5 }.ForEach(Console.WriteLine);
新列表 { 1, 3, 5 }.ForEach(Console.WriteLine);
回答by Ed Sykes
If there is a piece of code that you repeat all the time according to Don't Repeat Yourself you should put it in your own library and call that. With that in mind there are 2 aspects to getting the right answer here. The first is clarity and brevity in the code that calls the library function. The second is the performance implications of foreach.
如果根据 Don't Repeat Yourself 有一段代码你一直重复,你应该把它放在你自己的库中并调用它。考虑到这一点,在这里获得正确答案有两个方面。首先是调用库函数的代码清晰简洁。第二个是 foreach 的性能影响。
First let's think about the clarity and brevity in the calling code.
首先让我们考虑一下调用代码的清晰性和简洁性。
You can do foreach in a number of ways:
您可以通过多种方式执行 foreach:
- for loop
- foreach loop
- Collection.ForEach
- for循环
- foreach 循环
- 集合.ForEach
Out of all the ways to do a foreach List.ForEach with a lamba is the clearest and briefest.
在所有做 foreach List 的方法中,用 Lamba 做 ForEach 是最清晰、最简洁的。
list.ForEach(i => Console.Write("{0}\t", i));
So at this stage it may look like the List.ForEach is the way to go. However what's the performance of this? It's true that in this case the time to write to the console will govern the performance of the code. When we know something about performance of a particular language feature we should certainly at least consider it.
所以在这个阶段它可能看起来像 List.ForEach 是要走的路。然而这有什么表现呢?在这种情况下,写入控制台的时间确实会控制代码的性能。当我们对特定语言特性的性能有所了解时,我们当然至少应该考虑它。
According to Duston Campbell's performance measurements of foreachthe fastest way of iterating the list under optimised code is using a for loop without a call to List.Count.
根据Duston Campbell 对 foreach 的性能测量,在优化代码下迭代列表的最快方法是使用 for 循环而不调用 List.Count。
The for loop however is a verbose construct. It's also seen as a very iterative way of doing things which doesn't match with the current trend towards functional idioms.
然而,for 循环是一个冗长的结构。它也被视为一种非常迭代的做事方式,与当前的功能习语趋势不符。
So can we get brevity, clarity and performance? We can by using an extension method. In an ideal world we would create an extension method on Console that takes a list and writes it with a delimiter. We can't do this because Console is a static class and extension methods only work on instances of classes. Instead we need to put the extension method on the list itself (as per David B's suggestion):
那么我们能否获得简洁、清晰和性能呢?我们可以通过使用扩展方法。在理想的世界中,我们会在 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();
}
This code is going to used in many places so we should carry out the following improvements:
这段代码会用在很多地方,所以我们应该进行以下改进:
- Instead of using foreach we should use the fastest way of iterating the collection which is a for loop with a cached count.
- Currently only List can be passed as an argument. As a library function we can generalise it through a small amount of effort.
- Using List limits us to just Lists, Using IList allows this code to work with Arrays too.
- Since the extension method will be on an IList we need to change the name to make it clearer what we are writing to:
- 我们应该使用迭代集合的最快方式而不是使用 foreach,这是一个带有缓存计数的 for 循环。
- 目前只有 List 可以作为参数传递。作为一个库函数,我们可以通过少量的努力将其泛化。
- 使用 List 限制我们只能使用列表,使用 IList 也允许此代码与数组一起使用。
- 由于扩展方法将在 IList 上,我们需要更改名称以使其更清楚我们要写入的内容:
Here's how the code for the function would look:
该函数的代码如下所示:
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();
}
We can improve this even further by allowing the client to pass in the delimiter. We could then provide a second function that writes to console with the standard delimiter like this:
我们可以通过允许客户端传入分隔符来进一步改进这一点。然后我们可以提供第二个函数,它使用标准分隔符写入控制台,如下所示:
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();
}
So now, given that we want a brief, clear performant way of writing lists to the console we have one. Here is entire source code including a demonstration of using the the library function:
所以现在,鉴于我们想要一种简短、清晰的将列表写入控制台的高效方式,我们有了一个。这是完整的源代码,包括使用库函数的演示:
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();
}
}
}
=======================================================
================================================== ======
You might think that this should be the end of the answer. However there is a further piece of generalisation that can be done. It's not clear from fatcat's question if he is always writing to the console. Perhaps something else is to be done in the foreach. In that case Jason Bunting's answer is going to give that generality. Here is his answer again:
您可能认为这应该是答案的结尾。但是,还可以进行进一步的概括。从 fatcat 的问题中不清楚他是否总是在写到控制台。也许在 foreach 中还有其他事情要做。在这种情况下,Jason Bunting 的回答将给出一般性。这里又是他的回答:
list.ForEach(i => Console.Write("{0}\t", i));
That is unless we make one more refinement to our extension methods and add FastForEach as below:
除非我们对我们的扩展方法进行进一步改进并添加 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();
}
This allows us to execute any arbitrary code against every element in the collection using the fastest possible iteration method.
这允许我们使用最快的迭代方法对集合中的每个元素执行任意代码。
We can even change the WriteToConsole function to use FastForEach
我们甚至可以将 WriteToConsole 函数更改为使用 FastForEach
public static void WriteToConsole<T>(this IList<T> collection, string delimiter)
{
collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter));
}
So now the entire source code, including an example usage of FastForEach is:
所以现在整个源代码,包括 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();
}
}
}
回答by Lev Lukomsky
Also you can do join:
你也可以加入:
var qwe = new List<int> {5, 2, 3, 8};
Console.WriteLine(string.Join("\t", qwe));