诊断'CodeContracts需要未经证实:构造函数!= null'?

问题描述:

当C#CodeContracts静态检查器已启用时,我有几种方法报告警告“代码合同:要求未经证实:构造函数!= null”诊断'CodeContracts需要未经证实:构造函数!= null'?

这些特定的方法不会声明任何合约,也不会被任何方法调用。

如果我双击警告,visual studio会引导我执行对象的行。下面是有问题的方法之一:

public List<IStudentTermData> GetAllActive() 
{ 
    using (IObjectContext context = ContextFactory.Create()) 
    { 
     var studentTermDataSet = context.ObjectSet<IStudentTermData>(); 
     var studentSet = context.ObjectSet<IStudent>(); 

     // Helps out CodeContracts static checker 
     if(studentSet == null || studentTermDataSet == null) 
      return new List<IStudentTermData>(); 

     // Selecting the warning brings me to the next line 
     IQueryable<IStudentTermData> query = 
      from studentTermData in studentTermDataSet 
      join student in studentSet 
      on studentTermData.StudentId equals student.Id 
      where (student.Active) select studentTermData; 

     return query.ToList(); 
    } 
} 

我有没有表现出这样的警告其他几个非常类似的方法,我注意到他们不使用LINQ加入。我猜测我的LINQ查询正被解构成一些(可能为null)IQueryable对象,它会调用Join(),导致此警告。

这与CodeContracts静态检查器有什么关系?另外,为什么检查者抱怨,我该怎么做才能解决这个问题?

+0

可能在调用ToList()之前检查查询是否为null等于? –

+0

我试过了,但是Resharper表示'(query!= null)'总是会评估为true。我甚至忽略了Resharper的建议,并用查询的空检查重建,并没有任何效果。 – Rob

+0

请勿在“C#”前添加标题。这就是标签的用途。 –

这里似乎有一个错误。

您的查询desugars到:

​​

所谓的“构造”唯一的参数是Join方法的最后一个参数,而事实上,如果你的代码更改为:

var query = 
    studentTermDataSet.Join(studentSet, 
          studentTermData => studentTermData.StudentId, 
          student => student.Id, 
          Tuple.Create); 

然后它编译没有警告。

所不同的是在第一查询使用Join过载它接受一个Expression作为参数,而第二个需要Func(并返回一个IEnumerable)。

所以我认为表达式树的支持可能还没有完成。您可以在Code Contracts forum上发帖提问。