具有不同通用参数的C#通用返回类型

时间:2017-01-18 20:31:36

标签: c# generics csvhelper

我正在处理不同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'不能用作泛型类型或方法'CsvConfiguration.RegisterClassMap()'中的类型参数'TMap'。从'TMap'到'CsvHelper.Configuration.CsvClassMap'没有装箱或拆箱转换或类型参数转换。

所需的用法是:

        var records = CsvFile.Read<CacheEntryRequest, CacheEntryRequestMapper>(filename);

2 个答案:

答案 0 :(得分:5)

为了能够使用TMapTMap需要与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); 

答案 1 :(得分:3)

要添加@PeterBons提供的答案,可以像这样添加多个约束

public static IEnumerable<TR> Read<TR, TMap>(string filename) 
    where TMap : OneClass
    where TR : AnotherClass