Общий тип возврата 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
Другие вопросы по тегам