2016-11-24 3 views
1

После поиска на доске я не смог найти решение моей проблемы.Преобразование общей коллекции в список строк

Я написал следующий код, который работает очень хорошо:

public static void CreateFile(this List<string> lines,File_attribute fa) 
{ 
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(fa.OutpoutFolder+ fa.FileName)) 
    { 
     foreach (string line in lines) 
     { 

      file.WriteLine(line); 

     } 
    } 
} 

Теперь я хочу, чтобы иметь возможность сделать именно это с общей коллекцией объекта. Я хочу, чтобы каждое свойство просто было «ToStringed». Вот начало моего кода:

public static void CreateFile<T>(this List<T> lines, File_attribute fa) 
{ 
    List<string> mylist = new List<string>(); 
    ............... 
    ............... 

Любая помощь будет высоко оценена.

+0

Вы можете определить, что T имеет объект типа, просто добавьте объект T:. объект имеет ToString – anhoppe

+0

@anhoppe structs может быть 'ToString''d также –

+1

@anhoppe' T' уже объект ... –

ответ

1

Вот возможный альтернативный подход с использованием string.Join:

public static void CreateFile<T>(this List<T> lines, File_attribute fa) 
{ 
    File.WriteAllText 
    (
      Path.Combine(fa.OutpoutFolder, fa.FileName), 
      string.Join(Environment.NewLine, lines) 
    ); 
} 

Так string.Join будет внутренне назвать Object.ToString()!

+0

Объединение всего в одну строку может не быть лучшим подходом в зависимости от размера переданной коллекции. Возможно, OP использовал поток с итерацией по коллекции по какой-то причине, а затем, возможно, не ... – Igor

+0

@Igor Я поднял ту же самую озабоченность, что и комментарий в вашем собственном ответе ... Представьте, что OP имеет «Список » из 100 тысяч элементов ... не будет ли это плохой практикой * per se *? –

+0

@Igor ** Программисты тратят огромное количество времени на размышления о скорости некритических частей своих программ или беспокоятся о скорости их некритических частей, и эти попытки эффективности действительно оказывают сильное негативное влияние при отладке и обслуживании. Мы должны забыть о небольшой эффективности, скажем, примерно в 97% случаев: преждевременная оптимизация - это корень всех злых. ** http://wiki.c2.com/?PrematureOptimization –

2

Вы можете использовать LINQ для этого

public static void CreateFile<T>(this List<T> lines, File_attribute fa) 
{ 
    List<string> mylist = lines.Select(x => x.ToString()).ToList(); 
    ............... 
    ............... 
0
public static void CreateFile<T>(this List<T> lines) 
{ 
    List<string> mylist = new List<string>(); 
    var props = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); 
    foreach (var item in lines) 
    { 
     foreach (var prop in props) 
     { 
      var val = prop.GetValue(item); 
      // do what you want with val, you can call ToString() on it 
     } 
    } 
} 
+0

Вы уверены? что ваш ответ в порядке? :( –

+1

@ MatíasFidemraizer nope, но OP спрашивает о ToStringing «каждое свойство», поэтому, возможно, он хочет это сделать. –

+0

Meh Я считаю, что OP хотел сказать ** items ** вместо * свойств * –

1

Просто используйте ToString для каждого элемента, остальные могут остаться прежними:

public static void CreateFile<T>(this List<T> items, File_attribute fa) 
{ 
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(fa.OutpoutFolder + fa.FileName)) 
    { 
     foreach (T item in items) 
      file.WriteLine(item.ToString()); 
    } 
} 

Делая это таким образом, для огромного списка это позволит предотвратить приложение от выделения большого объема памяти до того он может писать что угодно на диск.

0

Хотя все происходит от System.Object и для них реализует .ToString() очень легко упустить из вида это как абонент и использовать его на типе, где вы не перезаписать .ToString() который затем выводить объекты типа вместо некоторых ожидаемого сообщения. Для лучшего контроля я бы настоятельно рекомендовал интерфейс, а затем использовал это как общее ограничение для вашего метода.

public interface ILine { 
    string GetLineOutput(); 
} 

Тогда в вашем классе.

public static void CreateFile(this List<T> lines, File_attribute fa) where T : ILine 
{ 
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(System.IO.Path.Combine(fa.OutpoutFolder, fa.FileName))) 
    { 
     foreach (ILine line in lines) 
     { 
      file.WriteLine(lin.GetLineOutput()); 
     } 
    } 
} 

Некоторой сторона отмечает

  1. При создании пути к файлу с переменной частью следует использовать System.IO.Path.Combine объединить эти части.
  2. Хорошая работа по использованию потока, а также запись в него по строкам, а не всех сразу, что может вызвать проблемы с памятью. Также хорошая работа по использованию using для вашего потока!
+0

Не так ли, инженерный? –

+0

@ MatíasFidemraizer - не IMO. Если вы должны были называть это из разных мест и никогда не перезаписывать 'ToString()' на тип, переданный в вас, вы получите вывод, содержащий не более чем квалифицированное имя типа, которое является неожиданным, но никогда не будет возникать никаких исключений. Единственный способ поймать его - это когда вы (кто-то из людей) действительно просмотрели результат. – Igor

+0

И теперь я подниму вам хороший вопрос: как вы реализуете 'ILine' на стороннем библиотека?: D –

Смежные вопросы