当启用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静态检查器有什么关系?此外,为什么检查员会抱怨,我该怎么做才能解决问题呢?
答案 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上发帖询问此问题。