Список Console.WriteLine и общий список

Я часто нахожу, что пишу код следующим образом:

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

Лучше было бы что-то вроде этого:

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

Я подозреваю, что есть какой-то умный способ сделать это, но я этого не вижу. У кого-нибудь есть лучшее решение, чем первый блок?

Сделай это:

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

EDIT: другим, которые ответили – он хочет, чтобы все они были в одной строке, с вкладками между ними. 🙂

Другой подход, просто для ударов:

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

новый список {1, 3, 5} .ForEach (Console.WriteLine);

Если есть fragment кода, который вы повторяете все время в соответствии с «Не повторяйте себя», вы должны поместить его в свою собственную библиотеку и вызвать это. Имея это в виду, есть два аспекта для получения правильного ответа здесь. Первая – это ясность и краткость в коде, который вызывает библиотечную функцию. Во-вторых, это последствия производительности foreach.

Сначала давайте подумаем о ясности и краткости в вызывающем коде.

Вы можете сделать foreach несколькими способами:

  1. для цикла
  2. цикл foreach
  3. Collection.ForEach

Из всех способов сделать список foreach.ForEach с lamba является самым ясным и кратчайшим.

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

Таким образом, на этом этапе это может выглядеть как List.ForEach – путь. Однако какова эффективность этого? Это правда, что в этом случае время записи на консоль будет определять производительность кода. Когда мы знаем что-то о производительности определенной языковой функции, мы должны, по крайней мере, ее рассмотреть.

Согласно измерениям производительности Duston Campbell foreach, самый быстрый способ перебора списка под оптимизированным кодом – использовать цикл for без вызова List.Count.

Однако цикл for – это многословная конструкция. Это также рассматривается как очень итеративный способ делать вещи, которые не соответствуют текущей тенденции к функциональным идиомам.

Так можем ли мы получить краткость, ясность и производительность? Мы можем использовать метод расширения. В идеальном мире мы бы создали метод расширения на консоли, который берет список и записывает его с помощью разделителя. Мы не можем этого сделать, потому что Console является статическим classом, а методы расширения работают только с экземплярами classов. Вместо этого нам нужно поместить метод расширения в самый список (согласно предложению Дэвида Б.):

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

Этот код будет использоваться во многих местах, поэтому мы должны выполнить следующие улучшения:

  • Вместо использования foreach мы должны использовать самый быстрый способ итерации коллекции, которая представляет собой цикл for с кешированным счетчиком.
  • В настоящее время только List может быть передан в качестве аргумента. В качестве библиотечной функции мы можем обобщить ее с помощью небольшого количества усилий.
  • Использование List ограничивает нас только списками, использование IList позволяет этому коду работать и с массивами.
  • Поскольку метод расширения будет на IList, нам нужно изменить имя, чтобы он стал более ясным, о чем мы пишем:

Вот как выглядит код функции:

 public static void WriteToConsole(this IList 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(this IList collection) { WriteToConsole(collection, "\t"); } public static void WriteToConsole(this IList 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(this IList collection) { WriteToConsole(collection, "\t"); } public static void WriteToConsole(this IList 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 {1, 2, 3, 4, 5}; var myDoubleList = new List {1.1, 2.2, 3.3, 4.4}; var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6}; var myFooList = new List {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(); } } } 

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

Вы можете подумать, что это должен быть конец ответа. Однако есть еще одно обобщение, которое можно сделать. Из вопроса жирного жителя неясно, всегда ли он пишет на консоль. Возможно, что-то еще предстоит сделать в преддверии. В этом случае ответ Джейсона Бантинга даст эту общность. Вот его ответ снова:

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

То есть, если мы не сделаем еще одно уточнение наших методов расширения и добавим FastForEach, как показано ниже:

 public static void FastForEach(this IList collection, Action actionToPerform) { int count = collection.Count(); for (int i = 0; i < count; ++i) { actionToPerform(collection[i]); } Console.WriteLine(); } 

Это позволяет нам выполнять любой произвольный код для каждого элемента в коллекции, используя самый быстрый способ итерации .

Мы можем даже изменить функцию WriteToConsole для использования FastForEach

 public static void WriteToConsole(this IList 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(this IList collection) { WriteToConsole(collection, "\t"); } public static void WriteToConsole(this IList collection, string delimiter) { collection.FastForEach(item => Console.Write("{0}{1}", item.ToString(), delimiter)); } public static void FastForEach(this IList collection, Action 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 {1, 2, 3, 4, 5}; var myDoubleList = new List {1.1, 2.2, 3.3, 4.4}; var myDoubleArray = new Double[] {12.3, 12.4, 12.5, 12.6}; var myFooList = new List {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(); } } } 
  List a = new List() { 1, 2, 3, 4, 5 }; a.ForEach(p => Console.WriteLine(p)); 

edit: ahhh он избил меня.

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

Редактировать: Черт возьми! занял слишком много времени, чтобы открыть визуальную студию для ее проверки.

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

Тогда позже…

 list.WriteLine(); 

Также вы можете присоединиться:

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