Reputation: 10824
I have following class:
public class Cmp
{
public List<Tuple<string, string>> Hdd { get; set; }
public string Cpu { get; set; }
public string MonitorModel { get; set; }
public List<Tuple<string, string>> OpticDriver { get; set; }
}
I am also using this code to convert List<Cmp>
to CSV:
public static void WriteToCsv<T>(IEnumerable<T> data)
{
var strBuilder = new StringBuilder();
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
foreach (PropertyDescriptor prop in props)
{
strBuilder.Append(prop.DisplayName); // header
strBuilder.Append(",");
}
strBuilder.AppendLine();
foreach (T item in data)
{
foreach (PropertyDescriptor prop in props)
{
strBuilder.Append(prop.Converter.ConvertToString(
prop.GetValue(item)));
strBuilder.Append(",");
}
strBuilder.AppendLine();
}
File.WriteAllText(@"C:\list.csv", strBuilder.ToString());
}
Just wondering How can I iterator over Hdd
and OpticDriver
properties inside WriteToCsv<T>
. Currently the result is like this:
Hdd Cpu MonitorModel OpticDriver
(Collection) CPU1 Monitor1 (Collection)
(Collection) CPU2 Monitor2 (Collection)
(Collection) CPU3 Monitor3 (Collection)
I want it to be like this:
Hdd Cpu MonitorModel OpticDriver
Hdd1-Hdd2 CPU1 Monitor1 Disk1-Disk2
Hdd1-Hdd2 CPU2 Monitor2 Disk1-Disk2
Hdd1-Hdd2 CPU3 Monitor3 Disk1-Disk2
Upvotes: 1
Views: 460
Reputation: 76787
You might have more Hdd
and OpticDriver
items for the same Cpu
and MonitorModel
, respectively, therefore you will need three cycles:
Cmp
Hdd
items of a given Cmp
itemOpticDriver
items of a given Cmp
item with a given Hdd
If you want to keep WriteToCsv generic, then check for the type of prop and if it is some kind of set, then you will need to implement an inner cycle for it. You can achieve this both iteratively or recursively, but the former is recommended. You will just make sure you mine all the multi-dimensional tuples you need. I recommend the usage of an array where you store as many iterators as you like and when an iterator finishes its set, set it to the first item of the given set and go to the next item of the previous set in the array, until the first iterator finishes its job. If this answer is unclear, let me know, I will give you the algorithm then.
Upvotes: 1
Reputation: 31663
Cast the value to List<Tuple<string,string>>
and handle it differently than other properties
foreach (PropertyDescriptor prop in props)
{
var value = prop.GetValue(item);
if(value is List<Tuple<string, string>> tupleList)
{
string tupleString = ConvertTupleListToString(tupleList);
strBuilder.Append(tupleString);
}
else
{
strBuilder.Append(prop.Converter.ConvertToString(value));
}
strBuilder.Append(",");
}
Instead of using generic List<Tuple<string,string>>
consider using your own List-like type with custom ToString()
implementation which will return whatever you want.
public class HddInfoList : List<Tuple<string, string>>
{
public HddInfoList(IEnumerable<Tuple<string, string>> collection) : base(collection)
{
}
public override string ToString()
{
//For example return first items of tuple separated by '-'
return string.Join("-", this.Select(m => m.Item1));
}
}
Upvotes: 1