具有不同泛型参数的 C# 泛型 Return 类型
C# Generic Return Type with Different Generic Parameter
我正在处理不同 CSV 文件的管道,因此想编写一个通用的 reader 和编写器,只需传递必要的类型。 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 抱怨:
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'.
期望的用法是:
var records = CsvFile.Read<CacheEntryRequest, CacheEntryRequestMapper>(filename);
为了能够使用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
或类似的东西。
可能 class CacheEntryRequest
有一个基数 class。那将是您的通用约束。
现在。假设你有一个像
这样的映射 class
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
我正在处理不同 CSV 文件的管道,因此想编写一个通用的 reader 和编写器,只需传递必要的类型。 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 抱怨:
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'.
期望的用法是:
var records = CsvFile.Read<CacheEntryRequest, CacheEntryRequestMapper>(filename);
为了能够使用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
或类似的东西。
可能 class CacheEntryRequest
有一个基数 class。那将是您的通用约束。
现在。假设你有一个像
这样的映射 classpublic 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