Как хорошая идея - это для использования контрактов кода в Профессионале Visual Studio 2010 года (т.е. никакая статическая проверка) для библиотек классов?

Я создаю библиотеки классов, некоторые, которые используются другими во всем мире, и теперь, когда я начинаю использовать Visual Studio 2010, я задаюсь вопросом, как хорошая идея это для меня для переключения на использование контрактов кода вместо регулярных операторов "if" старого стиля.

т.е. вместо этого:

if (fileName == null)
    throw new ArgumentNullException("fileName");

используйте это:

Contract.Requires(fileName != null);

Причина, которую я спрашиваю, состоит в том, что я знаю, что статическое средство проверки не доступно мне, таким образом, я немного озабочен некоторыми предположениями, что я делаю, что компилятор не может проверить. Это могло бы привести к библиотеке классов, не компилирующей для кого-то, который загружает ее, когда у них есть статическое средство проверки. Это, вместе с тем, что я не могу даже воспроизвести проблему, сделало бы ее утомительной для фиксации, и я заключу, что она не говорит красноречивее всяких слов к качеству моей библиотеки классов, если она по-видимому даже не компилирует из поля.

Таким образом, у меня есть несколько вопросов:

  • Находится статическое средство проверки на по умолчанию, если у Вас есть доступ к нему? Или есть ли установка, которую я должен включить в библиотеке классов (и так как у меня нет статического средства проверки, я не буду),
  • Действительно ли мои страхи являются неоправданными? Является вышеупомянутый сценарий настоящей проблемой?

Любой совет приветствовался бы.


Править: Позвольте мне разъяснить то, что я имею в виду.

Скажем, у меня есть следующий метод в классе:

public void LogToFile(string fileName, string message)
{
    Contracts.Requires(fileName != null);
    // log to the file here
}

и затем у меня есть этот код:

public void Log(string message)
{
    var targetProvider = IoC.Resolve<IFileLogTargetProvider>();
    var fileName = targetProvider.GetTargetFileName();
    LogToFile(fileName, message);
}

Теперь, здесь, МОК умирает, разрешает некоторый "случайный" класс, который предоставляет мне имя файла. Скажем, это для этой библиотеки, нет никакого возможного способа, которым я могу возвратить класс, который не даст мне непустое имя файла, однако, из-за природы вызова МОК, статический анализ не может проверить это и таким образом мог бы предположить, что возможное значение могло быть нулевым.

Следовательно, статический анализ мог бы прийти к заключению, что существует риск LogToFile метод, называемый с a null аргументу, и таким образом не удается создать.

Я понимаю, что могу добавить предположения коду, говоря, что компилятор должен взять его в качестве, учитывая, что fileName Я возвращаюсь из того метода, никогда не будет пустым, но если бы у меня нет статического анализатора (Профессионал VS2010), вышеупомянутый код скомпилировал бы для меня, и таким образом я мог бы оставить это как ошибку сна для кого-то с Окончательным для нахождения. Другими словами, не было бы никакого времени компиляции, предупредив, что могла бы быть проблема здесь, таким образом, я мог бы выпустить библиотеку как есть.

Таким образом, действительно ли это - реальный сценарий и проблема?

8
задан Lasse V. Karlsen 13 April 2010 в 18:18
поделиться

3 ответа

Если оба метода LogToFile и Log являются частью вашей библиотеки, возможно, что ваш Метод Log не будет компилироваться, как только вы включите статическую проверку. Это, конечно, также произойдет, когда вы предоставите код другим, которые компилируют ваш код с помощью статической проверки. Однако, насколько мне известно, статическая программа проверки вашего клиента не будет проверять внутреннее устройство поставляемой вами сборки. Он будет статически проверять собственный код на соответствие общедоступному API вашей сборки. Так что пока вы просто отправляете DLL, все будет в порядке.

Конечно, есть изменение в доставке библиотеки, которая имеет очень раздражающий API для пользователей, у которых действительно включена статическая проверка, поэтому я думаю, что рекомендуется поставлять вашу библиотеку только с определениями контрактов, если вы проверили удобство использования. API как со статической проверкой, так и без нее.

Обратите внимание на изменение существующих вызовов if (cond) throw ex на вызовы Contracts.Requires (cond) для вызовов общедоступного API, которые вы уже добавили в предыдущий выпуск. . Обратите внимание, что метод Requires генерирует другое исключение ( RequiresViolationException , если я правильно помню), чем то, что вы обычно вызываете ( ArgumentException ). В этой ситуации используйте перегрузку Contract.Requires . Таким образом, ваш интерфейс API останется неизменным.

2
ответ дан 6 December 2019 в 00:06
поделиться

Нет; статический анализатор никогда не помешает успешной компиляции (если только она не выйдет из строя!).

Статический анализатор предупредит вас о недоказанных предварительных / постусловиях, но не останавливает компиляцию.

0
ответ дан 6 December 2019 в 00:06
поделиться

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

Во-вторых, хотя статический анализ впечатляет, он не всегда может найти все пути , которые могут привести к нарушению инварианта. Однако хорошая новость заключается в том, что контракт Requires сохраняется во время выполнения - он обрабатывается на этапе преобразования IL - поэтому проверка существует как во время компиляции , так и время выполнения. В этом смысле он эквивалентен (но превосходит) обычной проверке if () .

Вы можете узнать больше о перезаписи среды выполнения, которую выполняет компиляция контракта кода здесь , вы также можете прочитать подробное руководство здесь .

РЕДАКТИРОВАТЬ: Основываясь на том, что я могу почерпнуть из руководства, я подозреваю, что описанная вами ситуация действительно возможна. Однако я думал, что это будут предупреждения, а не ошибки компиляции - и вы можете подавить их, используя System.Diagnostics.CodeAnalysis.SuppressMessage () . Пользователи вашего кода, у которых есть статический верификатор, также могут отмечать конкретные случаи, которые следует игнорировать, но это, безусловно, может быть неудобно, если их много.Я постараюсь найти время позже сегодня, чтобы составить окончательный тест вашего сценария (на данный момент у меня нет доступа к статическому верификатору).

Здесь есть отличный блог , который почти полностью посвящен кодовым контрактам, которые (если вы еще не видели) могут содержать интересующий вас контент.

2
ответ дан 6 December 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: