Общий тип возврата C# с другим общим параметром
Я работаю с конвейером различных CSV-файлов, поэтому хочу написать универсальное средство чтения и записи, просто передавая необходимые типы. RegisterClassMap() обычно принимает определенный вами Mapper. Первый пример - это рабочий код без использования обобщений.
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;
}
Далее следует моя неудачная попытка написать универсальный метод с универсальным параметром для типа Mapper:
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;
}
После чего RegisterClassMap жалуется:
Тип "TMap" нельзя использовать в качестве параметра типа "TMap" в универсальном типе или методе "CsvConfiguration.RegisterClassMap()". Конвертирование в бокс или распаковка или преобразование параметров типа из TMap в CsvHelper.Configuration.CsvClassMap отсутствует.
Желаемое использование будет:
var records = CsvFile.Read<CacheEntryRequest, CacheEntryRequestMapper>(filename);
2 ответа
Для того, чтобы иметь возможность использовать TMap
, TMap
должен быть совместим с типом ввода RegisterClassMap<T>
метод.
Вы можете сделать это, используя общие ограничения. См. https://msdn.microsoft.com/en-us/library/d5x73970.aspx.
В вашем случае вам нужно изменить сигнатуру метода на public static IEnumerable<TR> Read<TR, TMap>(string filename) where TMap : CsvClassMap
или что-то типа того.
Вероятно, класс CacheEntryRequest
имеет базовый класс. Это будет вашим общим ограничением.
Сейчас. при условии, что у вас есть класс отображения как
public class CustomCacheEntryRequestMapper : CsvClassMap
{
...
}
Затем вы можете вызвать свой метод так:
var records = CsvFile.Read<CacheEntryRequest, CustomCacheEntryRequestMapper >(filename);
Чтобы добавить к ответу, который дал @PeterBons, несколько ограничений, добавляются следующим образом
public static IEnumerable<TR> Read<TR, TMap>(string filename)
where TMap : OneClass
where TR : AnotherClass