繁体   English   中英

在编写具有多种类型的通用扩展方法时,键入推断问题

[英]Type inference problem when writing a generic extension method with more than one type

我正在为IEnumerable编写一个通用扩展方法,用于将对象列表映射到另一个映射对象列表。 这就是我希望该方法工作的方式:

IList<Article> articles = GetArticles();
return articles.Map<ArticleViewModel>(_mappingEngine);

这是方法:

public static IEnumerable<T2> Map<T1, T2>(this IEnumerable<T1> list, IMappingEngine engine)
{
    return list.Select(engine.Map<T1, T2>);
}

但是articles.Map<ArticleViewModel>(_mappingEngine); 给出编译错误。 问题是T1的类型推断不起作用。 我必须明确地这样称呼它:

articles.Map<Article, ArticleViewModel>(_mappingEngine);

如果我创建一个只有一个参数T1的扩展方法,如下所示:

public static IEnumerable<T1> DummyMap<T1>(this IEnumerable<T1> list, IMappingEngine engine)
{
    return list;
}

然后我可以像这样调用它,而不必指定T1:

articles.DummyMap(_mappingEngine);

有没有理由说编译器无法在Map的扩展方法中推断出T1的类型?

问题是T1的类型推断不起作用

实际上,问题不是T1 - 它是T2; 此推断中不使用返回类型。 所以你不能这样做。 一个选项可能是一个流畅的API,例如:

return articles.Map(_mappingEngine).To<SomeT2>();

有类似的东西:

public static MapProjection<T1> Map<T1>(this IEnumerable<T1> list, IMappingEngine engine)
{
    return new MapProjection<T1>(list, engine);
}
public class MapProjection<T1>
{
    private readonly IEnumerable<T1> list;
    private readonly IMappingEngine engine;
    internal MapProjection( IEnumerable<T1> list, IMappingEngine engine)
    {this.list = list; this.engine = engine;}

    public IEnumerable<T2> To<T2>()
    {
        return list.Select(engine.Map<T1, T2>());
    }
}

假设接口是这样的:

public interface IMappingEngine {
    Func<T1, T2> Map<T1, T2>();
}

我相信即使你提供T2而不提供T1,你也希望C#编译器推断T1的类型。

关键是你可以使用类型推断,或者只是不使用它。 你不能混合两个世界:

    public void M<T, S>(T t, S s)
    {
    }

    M<string>("hello", "world!")

此代码无法编译,但是:

    public void M<T, S>(T t, S s)
    {
    }

    M("hello", "world!")

..compiles。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM