Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CsvHelper to save derived class object from abstract class

Tags:

c#

csvhelper

[Serializable]
public abstract class AbstractModel : ObservableObject
{
    // nothing.
}

public class RealModel : AbstractModel 
{
    public string PropertyA {get; set;}
    public string PropertyB {get; set;}
}

Note that ObservableObject is from Mvvm-light.

With above models, I used CsvHelper as below.

AbstractModel instance = new RealModel()
                             {
                                 PropertyA = "foo",
                                 PropertyA = "bar"
                             };

using (TextWriter file = new StreamWriter("path"))
using (var csv = new CsvWriter(file))
{
    csv.WriteRecord(instance);
}

It throws error as below;

No properties are mapped for type 'AbstractModel'

It works fine when I set RealModel instance = new RealModel(); instead. But, I have various derived classes and want to save them in a single Save method.

How can I do?

like image 678
Youngjae Avatar asked Oct 31 '22 12:10

Youngjae


1 Answers

I know this is three years old, but I was attempting to do the same thing, and I've found a hack to get it to work.

The offending code in csvHelper is the following:

public virtual Type GetTypeForRecord<T>(T record)
{
    var type = typeof(T);
    if (type == typeof(object))
    {
        type = record.GetType();
    }

    return type;
}

The C# generic that is passed down to this method is determined at compile time, so T is always going to be the base class, not the derived class, but if you cast to to type object before calling WriteRecord, the method will use GetType(), which will return the derived type.

AbstractModel instance = new RealModel()
                             {
                                 PropertyA = "foo",
                                 PropertyA = "bar"
                             };

using (TextWriter file = new StreamWriter("path"))
using (var csv = new CsvWriter(file))
{
    csv.WriteRecord((object)instance);
}
like image 177
Dru Steeby Avatar answered Nov 15 '22 05:11

Dru Steeby