Диагностика «CodeContracts требует недоказанного: конструктор! = Ноль»? - PullRequest
2 голосов
/ 08 августа 2011

У меня есть несколько методов, которые выдают предупреждение «Кодовые контракты: требуется недоказанный: конструктор! = Ноль» , когда включена статическая проверка C # CodeContracts .

Эти конкретные методы не объявляют никаких контрактов и не вызываются никакими методами, которые делают.

Если я дважды щелкаю предупреждения, Visual Studio направляет меня к строке, создающей экземпляр * 1009.* объект.Вот один из обидных методов:

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 Ответ

3 голосов
/ 09 августа 2011

Кажется, здесь есть ошибка.

Ваш запрос обрабатывается следующим образом:

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 , чтобы спросить об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...