I have a List of object of Tag type which is a my class inherited from SortedList<DateTime, T>. To allow add several Tag objects of different types (int, float, string), I created an interface called ITag. Tag objects can be have different sizes and different dates.
So I need to export this List of SortedList in a CSV file and my initial idea was to convert all tag object into a big SortedList<DateTime, List<string>> which it has like "Keys" all distinct tag dates and like "Values" a list of tags values in that specific time.
| 01/01/2024 00:01| 4, 6, "AAA" |
| 01/01/2024 00:02 | 2, , 8 |
I use a list for values because my CSV class accept a row of List<string>. That SortedList<DateTime, List<string>> take up huge memory and time to create, so I discared this method.
I thinked to delegate CSV class to "convert" my List of SortedList to CSV file getting a date one at thime with associate values founded and writing a single row. But I don't like that CSV class should be know how it's done Tag object or ITag object, it should be neutral taking a generic collection to elaborate.
public void Main()
{
Tag<float?> m = new Tag<float?>();
Tag<string?> o = new Tag<string?>();
Tag<int?> d = new Tag<int?>();
m.Add(new DateTime(2000, 1, 1), 1);
o.Add(new DateTime(2000, 1, 1), 2);
m.Add(new DateTime(2000, 1, 2), 4);
o.Add(new DateTime(2000, 1, 3), "AAA");
d.Add(new DateTime(2000, 1, 4), 6);
d.Add(new DateTime(2000, 1, 5), null);
d.Add(new DateTime(2000, 1, 1), 3);
List<ITag> listTag = new(){ m, o,d };
CSV? csvFile = new CSV(path, FileAccess.Write, CSVLocalCultureInfo);
csvFile.WriteLocal(listTag);
}
public class CSV : IDisposable
{
public void WriteLocal(List<ITag> listTag)
{
try
{
var dates = listTag.SelectMany(x => x.Keys).Distinct();
int tagNum = listTag.Count;
foreach (DateTime d in dates)
{
List<string?> tagValues = new(new string[tagNum]);
for (int j = 0; j < tagNum; j++)
{
object? value = null;
if (listTag[j].TryGetValue(d, out value))
{
tagValues[j] = value == null
? "No Data"
: value.ToString().ToString(_nameCultureLocal).Replace("\n", "");
}
}
CreateRowLocal(d, tagValues);
}
}
catch (Exception ex)
{
throw new FileException("Error");
}
}
}
public class Tag<T> : SortedList<DateTime, T?>, ITag, IEquatable<Tag<T>>
{
bool ITag.TryGetValue(DateTime key, out object? value)
{
T? val = default;
bool result = TryGetValue(key, out val);
value = (object?)val;
return result;
}
}
public interface ITag : IEquatable<ITag>
{
...
public bool TryGetValue(DateTime key, out object value);
...
}
For example, file destination should be:
| Date | Tag1 | Tag2 | Tag3 |
|---|---|---|---|
| 01/01/2024 00:00 | 2 | AAA | 6 |
| 01/01/2024 00:30 | 3 | BBB | No Data |
| ... | ... | ... | ... |