簡體   English   中英

如何在擴展方法中獲取'this'參數的泛型類型參數?

[英]How can I get the generic type parameter of the 'this' parameter in an extension method?

我正在嘗試將以下方法轉換為IEnumerable上的擴展方法:

private static IEnumerable<TTarget> MapList<TSource, TTarget>(IEnumerable<TSource> source)
{
    return source.Select(
            element =>
                _mapper.Map<TSource, TTarget>(element)
        ).ToList();
}

現在它被稱為這樣:

var sourceList = new List<SourceType>();
return MapList<SourceType, TargetType>(sourceList);

但我想這樣稱呼它:

var sourceList = new List<SourceType>();
return sourceList.MapTo<TargetType>();

我試過這樣做:

public static IEnumerable<TTarget> MapTo<TTarget>(this IEnumerable<TSource> source)
{
    return source.Select(
            element =>
                Mapper.Map<TSource, TTarget>(element)
        ).ToList();
}    

但是我找不到類型或名稱空間TSource因為它沒有包含在方法的類型參數列表中。 我可以讓它像這樣工作:

public static IEnumerable<TTarget> MapTo<TSource, TTarget>(this IEnumerable<TSource> source)
{
    return source.Select(
            element =>
                Mapper.Map<TSource, TTarget>(element)
        ).ToList();
}

但是我必須這樣稱呼它:

var sourceList = new List<SourceType>();
sourceList.MapTo<SourceType, TargetType>();

我覺得它不像sourceList.MapTo<TargetType>()那樣清晰。

有什么辦法可以做我想要的嗎?

調用中沒有足夠的信息來完全確定傳遞給MapTo的泛型類型參數,而C#不支持僅推斷某些類型。 您必須指定所有類型或不指定任何類型。

但是,您可以通過重新設計界面來解決這個問題。 這只是一個解決方案:

public sealed class Mappable<TSource>
{
    private readonly IEnumerable<TSource> source;

    public Mappable(IEnumerable<TSource> source)
    {
        this.source = source;
    }

    public IEnumerable<TTarget> To<TTarget>()
    {
        return source.Select(
                element =>
                    Mapper.Map<TSource, TTarget>(element)
            ).ToList();
    }
}

public static class Extensions
{
    public static Mappable<TSource> Map<TSource>(this IEnumerable<TSource> source)
    {
        return new Mappable<TSource>(source);
    }
}

現在你可以這樣稱呼它:

var sourceList = new List<SourceType>();
var target = sourceList.Map().To<TargetType>();

或者,如果您放棄使用擴展方法,您可以這樣做:

public static class MapTo<TTarget>
{
    public static IEnumerable<TTarget> From<TSource>(IEnumerable<TSource> source)
    {
        return source.Select(
                element =>
                    Mapper.Map<TSource, TTarget>(element)
            ).ToList();
    }
}

並稱之為:

var sourceList = new List<SourceType>();
var target = MapTo<TargetType>.From(sourceList);

這些都不是特別優雅。 如果您更喜歡這種語法而不是完全指定每次調用的通用參數,則由您決定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM