[英]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.