其他分享
首页 > 其他分享> > CodeGo.net>我如何在扩展方法中获得’this’参数的泛型类型参数?

CodeGo.net>我如何在扩展方法中获得’this’参数的泛型类型参数?

作者:互联网

我正在尝试将以下方法转换为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);

这些都不是特别优雅.如果您希望使用这种语法,而不是在每个调用中完全指定通用参数,则取决于您.

标签:generics,extension-methods,c
来源: https://codeday.me/bug/20191029/1960147.html