Контракты кода .NET: может ли он стать более базовым, чем этот? - PullRequest
5 голосов
/ 09 августа 2009

Я просто возился, чтобы ответить на чей-то вопрос здесь, о переполнении стека, когда я заметил предупреждение о статической проверке изнутри моей Visual Studio (2008):

string[] source = { "1", "A", "B" };
var sourceObjects = Array.ConvertAll(source, c => new Source(c)).ToArray();

Я получаю сообщение требуется непроверенный источник! = Ноль . Мне кажется довольно очевидным, что это не так. Это всего лишь один пример, конечно. С другой стороны, некоторые изящные вещи, кажется, работают довольно хорошо.

Я использую релиз 1.2.20518.12 (18 мая). Я нахожу контракты кода очень интересными, но у кого-нибудь еще были подобные случаи? Считаете ли вы текущую реализацию пригодной для использования на практике, или вы считаете ее чисто академической на данный момент?

Я сделал это вики-сообществом, но я хотел бы услышать некоторые мнения:)

1 Ответ

16 голосов
/ 09 августа 2009

Это имеет больше смысла, если вы разделите два вызова вверх:

string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();

Теперь он указывает на последнюю строку как проблему. Другими словами, вызов Array.ConvertAll знает, что источник не является нулевым, но вызов ToArray() не знает, что tmp не будет нулевым.

(Ваш пример также немного сбивает с толку из-за использования имени source в вашем исходном коде - ошибка все равно будет использовать source, даже если вы называете свою переменную как-то совершенно иначе, так как это относится к первый параметр в Enumerable.ToArray.)

По сути, я считаю, что все это будет работать, когда Array.ConvertAll получит соответствующее пост-условие ненулевого значения. До тех пор это сделает свое дело:

string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();

Я согласен, что такие вещи раздражают, но я уверен, что они быстро улучшатся, поскольку MS добавляет все больше и больше контрактов в BCL. Важно отметить, что это не проблема с самой статической проверкой.

(На самом деле, Array.ConvertAll также не имеет предусловия - если вы установите для переменной source значение null во втором фрагменте кода выше, он все равно не будет жаловаться.)

...