为什么不能推断出这些泛型类型?

时间:2011-12-07 15:42:48

标签: c# .net generics type-inference

我有以下代码:

public static class CardView {
    public static object Column<TModel, TResult>(Func<TModel, TResult> field) {
        return null;
    }
}

public class Person 
{
    public string Name { get; set; }
    public bool Gender { get; set; }
}

void Main()
{
    var model = new Person() { Name = "Andre", Gender = true };

    var b = CardView.Column(model => model.Name); // ERROR
    // The type arguments for method 'UserQuery.CardView.Column<TModel,TResult>(System.Func<TModel,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
}

由于某种原因,它无法推断Column方法的泛型类型。我需要知道原因。我不能放弃类型推断并自己指定类型,因为它只是一个大问题的案例研究,它将是不可或缺的。

修改

我拼错了代码= /刚刚修好了

4 个答案:

答案 0 :(得分:7)

为了让编译器执行类型推断,必须给它一些类型信息。在这种情况下,它提供的唯一信息是无类型的lambda表达式。编译器真的没有什么可以继续下去的。

有几种方法可以解决这个问题。最简单的方法是向lambda参数添加一个类型

var b = CardView.Column((Person m) => m.Name);

答案 1 :(得分:2)

技术答案是“因为规范并没有说你能做到”。引用the spec,第7.5.2节(类型推断):

  

7.5.2.1第一阶段

     

对于每个方法参数Ei:

     
      
  1. 如果Ei是匿名函数,则是显式参数类型推断   (§7.5.2.7)由Ei制成Ti
  2.   
  3. 否则,如果Ei的类型为U和xi   是一个值参数,然后从U到下限推断   的Ti。
  4.   
  5. 否则,如果Ei具有类型U并且xi是ref或out参数   然后从U到Ti进行精确推断。
  6.   
  7. 否则,不会对此参数进行推断。
  8.   

  

7.5.2.7显式参数类型推断

     

在下面,从表达式E到类型T进行显式参数类型推断   方式:

     
      
  • 如果E是显式类型的匿名函数,参数类型为U1 ... Uk和T是带参数的委托类型或表达式树类型   类型V1 ... Vk然后为每个Ui进行精确推理(第7.5.2.8节)   从Ui到相应的Vi。
  •   

由于示例中的匿名函数未显式输入,因此无法进行推理。这也告诉我们,要进行推理,您可以通过指定函数的类型来帮助:

var b = CardView.Column((Person m) => m.Name); 

现在这显然是Func<Person, string>,因此推断是成功的。

答案 2 :(得分:1)

在该方法签名中没有TModel参数(或使用TModel的泛型类型),因此编译器不知道m的类型。

答案 3 :(得分:0)

您编辑的代码无法编译。您不能将model用作lambda参数,因为您已将其声明为局部变量。看来你想通过使用已经声明的那种类型的本地来告诉编译器lambda参数是Person。但那不行。

通知编译器类型的正确方法是在lambda中显式声明它,正如其他人所说:

var b = CardView.Column((Person m) => m.Name); 

或为泛型方法提供类型参数:

var b = CardView.Column<Person, string>(m => m.Name);