As mentioned in linked question, you may use ExpandoObject to serialize dictionary.
The following code will work for writing to CSV only, it's converting classA objects to ExpandoObject during serialization, including Amount property which is added manually.
public static List<dynamic> ToExpandoObjects(IReadOnlyList<classA> aObjects)
{
var allKeys = aObjects
.SelectMany(a => a.Dict.Keys)
.Distinct()
.ToHashSet();
var result = new List<dynamic>();
foreach (var a in aObjects)
{
var asExpando = new ExpandoObject();
var asDictionary = (IDictionary<string, object>)asExpando;
asDictionary[nameof(classA.Amount)] = a.Amount;
foreach (var key in allKeys)
{
if(a.Dict.TryGetValue(key, out var value))
asDictionary[key] = value;
else
asDictionary[key] = null;
}
result.Add(asExpando);
}
return result;
}
...
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(ToExpandoObjects(records));
}
E.g. called as:
var records = new[] {
new classA
{
Amount = 15,
Dict = new Dictionary<string,string>{["a1"] = "a2",["b1"] = "b2"}
},
new classA
{
Amount = 15,
Dict = new Dictionary<string,string>{["c1"] = "c2",["b1"] = "b2"}
}
};
StringBuilder sb = new StringBuilder();
using (var writer = new StringWriter(sb))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(ToExpandoObjects(records));
}
Console.WriteLine(sb.ToString());
produces
| Amount |
a1 |
b1 |
c1 |
| 15 |
a2 |
b2 |
|
| 15 |
|
b2 |
c2 |