[英]C# Extension method on List with specific type
我有以下2种扩展方法
namespace Services.Resources.Extensions
{
public static class DataMapExtensions
{
public static T ToDTO<T>(this BaseModel model)
{
return Mapper.Map<T>(model);
}
public static List<T> ToDTO<T>(this List<BaseModel> models)
{
return Mapper.Map<List<T>>(models);
}
}
}
第一种方法非常好。
//Note: FlightRoute inherits BaseModel
FlightRouteDTO foo = new FlightRoute().ToDTO<FlightRouteDTO>(); //This works!
但是,第二种方法似乎不起作用。
List<FlightRouteDTO> bar = new List<FlightRoute>().ToDTO<FlightRouteDTO>(); //This doesn't work!
编译器说
错误CS1929'List <FlightRoute>'不包含'ToDTO'的定义,并且最佳扩展方法重载'DataMapExtensions.ToDTO <FlightRouteDTO>(List <BaseModel>)'需要类型为'List <BaseModel>'的接收器
但FlightRoute
的类型为BaseModel
。 如果我将bar
的类型更改为显式为List<BaseModel> ...
则问题就会消失。
List<FlightRouteDTO> bar = new List<BaseModel>().ToDTO<FlightRouteDTO>(); //Why does it only work this way?
我错过了一些明显的东西吗
这只是预期的行为:您正在尝试使用List<FlightRoute>
作为List<BaseModel>
,但仅仅因为FlitghtRoute
从BaseModel
继承而不使List<FlitghtRoute>
继承自List<BaseModel>
:它们是完全不同的类型。
相反,你可以做的是利用协方差 ,使用接口而不是具体类型。
通过将方法签名更改为以下内容,您将注意到不会生成编译器错误:
public static List<T> ToDTO<T>(this IEnumerable<BaseModel> models)
{
return Mapper.Map<List<T>>(models);
}
这是因为IEnumerable<T>
是一个具有协变类型参数的接口。 通过查看引用源 ,您将注意到此接口声明为out T
作为泛型类型参数,这表示T
是协变的,并且当我们使用IEnumerable<T>
时可以用任何继承的类型替换。
您可以引入带约束的第二个类型参数:
public static List<T> ToDTO<T, K>(this List<K> models) where K : BaseModel
{
return Mapper.Map<List<T>>(models);
}
解决这个问题的更好方法可能是更改签名,如下所示:
public static List<T> ToDTO<T>(this IEnumerable<BaseModel> models)
{
return Mapper.Map<List<T>>(models);
}
您实际上不需要接受List
,因为您没有使用值执行任何“特定于列表”的操作,并且AutoMapper会理解您传递给它的任何“集合”类型。 IEnumerable<T>
就足够了,因为它与T
,它现在可以正常工作:
// works
List<FlightRouteDTO> bar = new List<FlightRoute>().ToDTO<FlightRouteDTO>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.