C#:当有多个类型参数时,为什么泛型类型推断不起作用?

时间:2012-02-19 23:14:50

标签: c# generics

以下是两个样本:

这很好用:

void Main()
{
    var list = Queryable.ProjectTo(typeof(Projection));
}

public static class QueryableExtensions
{
    public static ProjectionList<T> ProjectTo<T>(this IQueryable<T> queryable, Type projectionType)
    {
        return new ProjectionList<T>(queryable, projectionType);
    }
}

这会引发以下错误:

  

使用通用方法   'QueryableExtensions.ProjectTo(System.Linq.IQueryable)'   需要2个类型参数

void Main()
{
    var list = Queryable.ProjectTo<Projection>();
}

public static class QueryableExtensions
{
    public static ProjectionList<T, P> ProjectTo<T, P>(this IQueryable<T> queryable)
    {
        return new ProjectionList<T, P>(queryable);
    }
}

当然第一个例子需要1个类型参数,但编译器可以弄清楚它是什么,所以我不需要提供任何参数。第二个例子需要2个类型的参数,但是编译器知道什么是T,那为什么它不仅需要一个无法推断的?

对于记录我在我的代码中使用第一个例子就好了,但我更喜欢第二个的语法更好,并且可能存在我希望具有投影的泛型类型的情况。有没有办法实现这个目标,还是我咆哮错误的树?

谢谢!

2 个答案:

答案 0 :(得分:5)

问题不在于2个参数,而是从哪里推断它?通用参数推断仅查看参数,特别是不考虑返回类型。参数中没有任何内容可以表明P.需要通用类型推断提供所有,或者明确指定所有。有趣的是,曾经提到过“mumble-typing”,正如我所解释的那样(因为它从未被完全定义)会允许你混合搭配,就像你想要的那样。想象:

blah.ProjectTo<?,SomeType>();

(确切的语法并不重要,因为这个语言特征不存在) - 但它意味着“有2个genericmtype参数;你(编译器)找出第一个参数;第二个是SomeType”。 / p>

答案 1 :(得分:4)

这是因为通用参数推断仅适用于输入参数。在第二个示例中,P参数仅出现在返回类型中,因此推理不起作用。所以当你写:

var list = Queryable.ProjectTo<Projection>();

TProjection,但P对你来说是什么?

但即使你写:

ProjectionList<Projection, FooBar> list = Queryable.ProjectTo();

它仍然不起作用。