I'm working with a pipeline of different CSV files so wanting to write a generic reader and writer, just passing the necessary types. RegisterClassMap() normally takes a Mapper you defined. The first example is working code not using generics.
public static IEnumerable<CacheEntryRequest> ReadCacheRequestFile(string filename)
{
List<CacheEntryRequest> requests;
using (var sr = new StreamReader(filename))
{
var csv = new CsvReader(sr);
csv.Configuration.RegisterClassMap<CacheEntryRequestMapper>();
requests = csv.GetRecords<CacheEntryRequest>().ToList();
}
return requests;
}
What follows is my failing attempt to write a generic method with a generic parameter for the Mapper type:
public static IEnumerable<TR> Read<TR, TMap>(string filename)
{
List<TR> records;
using (var sr = new StreamReader(filename))
{
var csv = new CsvReader(sr);
csv.Configuration.RegisterClassMap<TMap>();
records = csv.GetRecords<TR>().ToList();
}
return records;
}
After which RegisterClassMap complains:
The type 'TMap' cannot be used as a type parameter 'TMap' in the generic type or method 'CsvConfiguration.RegisterClassMap()'. There is no boxing or unboxing conversion or type parameter conversion from 'TMap' to 'CsvHelper.Configuration.CsvClassMap'.
Desired usage would be:
var records = CsvFile.Read<CacheEntryRequest, CacheEntryRequestMapper>(filename);
In order to be able to use TMap
, TMap
needs to be compatible with the input type of the RegisterClassMap<T>
method.
You can do that using generic constraint. See https://msdn.microsoft.com/en-us/library/d5x73970.aspx.
In your case you will need to change the method signature to public static IEnumerable<TR> Read<TR, TMap>(string filename) where TMap : CsvClassMap
or something like that.
Probably the class CacheEntryRequest
has a base class. That will be your generic constraint.
Now. assuming you have a mapping class like
public class CustomCacheEntryRequestMapper : CsvClassMap
{
...
}
You can then call your method like:
var records = CsvFile.Read<CacheEntryRequest, CustomCacheEntryRequestMapper >(filename);