诊断'CodeContracts需要unproven:constructor!= null'?

时间:2011-08-08 04:40:03

标签: c# linq linq-to-entities code-contracts

当启用C#CodeContracts静态检查程序时,我有几种方法可以报告警告“代码约定:需要unproven:constructor!= null”

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

如果我双击警告,visual studio会将我引导到实例化IQueryable<TEntity>对象的行。这是一种令人讨厌的方法:

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查询被解构为一些(可能是空的)IQueryable对象,在其上调用Join(),导致此警告。

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

1 个答案:

答案 0 :(得分:3)

这里似乎有一个错误。

您的查询涉及:

IQueryable<IStudentTermData> query =
    studentTermDataSet.Join(studentSet,
                            studentTermData => studentTermData.StudentId,
                            student => student.Id,
                            (studentTermData, student) => new {studentTermData, student})
                      .Where(s => (s.student.Active))
                      .Select(std => std.studentTermData);

唯一称为“构造函数”的参数是Join方法的最后一个参数,实际上,如果将代码更改为:

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

然后它会在没有警告的情况下编译。

不同之处在于,第一个查询使用Join重载,其中Expression作为参数,而第二个查询使用Func(并返回IEnumerable )。

所以我认为对表达式树的支持可能尚未完成。您可以在Code Contracts forum上发帖询问此问题。