.Net 3.5 Реализация String.IsNullOrWhitespace с контрактами кода - PullRequest
4 голосов
/ 01 февраля 2011

Я пытаюсь использовать контракты в моем проекте .Net 3.5 (C #).Я нашел там, где написал что-то вроде if (string.IsNullOrEmpty(s) || string.IsNullOrEmpty(s.Trim())) throw new ArgumentException("Required", "s"); в начале методов.

Я мог бы хранить их там и использовать устаревшие контракты.Я мог бы изменить его на Contract.Requires(s!= null && string.IsNullOrEmpty(s.Trim()));.Но помимо того, что я не совсем уверен в правильности или производительности части условия Пробелы , они неубедительны (мнение).

Вместо этого я попытался инкапсулировать условие в метод дляиспользовать в договорах.Проблема в том, что я до сих пор не могу понять, как описательно описать часть Пробелы .Статическая проверка находит несколько проблем в зависимости от того, как я ее пишу.

Я хотел бы услышать комментарии о целесообразности проверок содержимого данных, таких как эта, для пробелов, КАК ХОРОШО, КАК правильное определение.

public static class str
{
    [Pure]
    public static bool IsNullOrWhitespace(string s)
    {
      Contract.Ensures(s != null || Contract.Result<bool>());
      Contract.Ensures((s != null && !Contract.ForAll<char>(s, c => char.IsWhiteSpace(c))) || Contract.Result<bool>());

      if (s == null) return true;

      for (var i = 0; i < s.Length; i++)
      {
        if (!char.IsWhiteSpace(s, i))
        {
          Contract.Assume(!Contract.ForAll<char>(s, c => char.IsWhiteSpace(c)));
          return false;
        }
      }


      return true;
    }
}

Это может быть неаккуратным, но мой первоначальныйМетод экспериментов здесь.Утверждения на a, b и c не выполняются или не подтверждены.

static void Test()
{
  string a = null;
  string b = "";
  string c = "     ";
  string d = "xyz";
  string e = "  xyz  ";

  if (!str.IsNullOrWhitespace(a))
  {
    Contract.Assert(a != null);
    a = a.Trim();
  }

  if (!str.IsNullOrWhitespace(b))
  {
    Contract.Assert(b != null && b != "");
    b = b.Trim();
  }

  if (!str.IsNullOrWhitespace(c))
  {
    Contract.Assert(c != null && c != "     ");
    c = c.Trim();
  }

  if (!str.IsNullOrWhitespace(d))
  {
    d = d.Trim();
  }

  if (!str.IsNullOrWhitespace(e))
  {
    e = e.Trim();
  }
}

1 Ответ

2 голосов
/ 03 февраля 2011

Вот встроенный контракт из .NET 4:

Contract.Ensures(
    (Contract.Result<bool>() && ((str == null) || (str.Length == 0)))
    ? ((bool) true)
    : ((Contract.Result<bool>() || (str == null))
      ? ((bool) false)
      : ((bool) (str.Length > 0)))

, null, "Contract.Result<bool>() && (str == null || str.Length == 0) ||\r\n!Contract.Result<bool>() && str != null && str.Length > 0");

Несмотря на всю сложность, вы можете видеть, что здесь нет упоминания о пробелах. Я пробовал несколько раз, но не могу заставить работать что-то, что удовлетворит статическую проверку.

Похоже, из-за нескольких проблем я не смог написать это, поэтому я задал несколько вопросов на форуме Code Contracts.

Мой контракт был:

Contract.Ensures(Contract.Result<bool>() ==
                 (s == null || Contract.Exists(s, char.IsWhiteSpace)))
...