我有以下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!
编译器在说
Error CS1929 'List< FlightRoute>' does not contain a definition for 'ToDTO' and the best extension method overload 'DataMapExtensions.ToDTO< FlightRouteDTO>(List< BaseModel>)' requires a receiver of type '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>
: 它们是完全不同的类型。
相反,您可以利用 Covariance 的使用,使用接口(interface)而不是具体类型。
通过将您的方法签名更改为以下内容,您会注意到不会生成编译器错误:
public static List<T> ToDTO<T>(this IEnumerable<BaseModel> models)
{
return Mapper.Map<List<T>>(models);
}
那是因为 IEnumerable<T>
是具有协变 类型参数的接口(interface)。通过查看 reference source , 你会注意到这个接口(interface)是用 out T
声明的作为通用类型参数,表示 T
是协变的,当我们使用 IEnumerable<T>
时可以被任何继承的类型替换.
关于具有特定类型的 List 上的 C# 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50081181/