2012-02-19 113 views
4

这里有两个样品:C#:为什么泛型类型推断工作时有多个类型参数?

这工作正常:

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); 
    } 
} 

这引发以下错误:

Using the generic method 'QueryableExtensions.ProjectTo(System.Linq.IQueryable)' requires 2 type arguments

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是什么,为什么它不仅需要无法推断的那个?

为了记录我在代码中使用第一个例子很好,但是我更喜欢第二个例子的语法,可能会出现这种情况,我想要使用投影的泛型类型。有什么办法可以达到这个目的吗?还是我在咆哮错误的树木?

谢谢!

回答

5

该问题不是2个参数,而是:从哪里可以推断出它?通用参数推理仅查看参数,并且不具体考虑返回类型。在建议P的参数中没有任何内容。要求泛型类型推断提供所有,或者全部都是明确指定的。有趣的是,曾经有人提到过“嘟嘟typing”“,正如我对它的解释(因为它从来没有完全定义过)会允许你混合搭配,就像你想要的那样。试想一下:

blah.ProjectTo<?,SomeType>(); 

(确切的语法并不重要,因为这种语言特性不存在) - 但这意味着“有2个genericmtype参数;你(编译)计算出的第一个参数;在其次是SomeType“。

+0

感谢您的详细解答!但是你问,“从哪里推断出来?”在第一个例子中,它推断T,所以对于第二个例子来说,它不能以同样的方式推断T,因为T是一个方法参数,然后接受P的1类型参数,即1个未推断类型?我知道这并不重要,但看起来在这个例子中技术上可行,不是吗? – 2012-02-19 23:29:12

4

这是因为泛型参数推理仅适用于输入参数。在第二个示例中,P参数仅在返回类型中显示,因此推理无法工作。所以,当你写:

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

TProjection但对你有什么P

但是,即使你写:

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

它仍然是行不通的。

+0

这两个示例中的IQueryable 都不是T,因为它是扩展方法,因此推断为输入参数? – 2012-02-19 23:34:37