Как заставить Code Contracts поверить, что переменная не равна нулю? - PullRequest
10 голосов
/ 05 сентября 2011

У меня есть какой-то фабричный метод

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        return result;
    }

При попытке создать проект я получаю предупреждение:

CodeContracts: обеспечивает недоказанность: Contract.Result ()! =null

Я понимаю, что интерфейс IUnityContainer не имеет никаких контрактов, поэтому Code Contracts считает, что переменная может быть нулевой, и нет никакого способа доказать, что Create () вернет ненулевой результат.

Как в этом случае я могу заставить Code Contracts поверить, что результат переменная не равна нулю?

Сначала я попытался вызвать Contract.Assert

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        Contract.Assert(result != null);

        return result;
    }

Но этопринимает еще одно предупреждение:

CodeContracts: подтвердить недоказано

Я попытался сделать проверку на ноль, и это делает все предупреждения исчезли:

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        if (result == null)
        {
            throw new InvalidOperationException();
        }

        return result;
    }

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

Спасибо.

Ответы [ 3 ]

16 голосов
/ 05 сентября 2011

I думаю вы хотите Contract.Assume:

Contract.Assume(result != null);

Из документов:

Указывает инструментам анализа кода:Предположим, что указанное условие истинно, даже если оно не может быть статически доказано, что оно всегда истинно.

Это все равно будет проверять результат во время выполнения, если вы правильно настроили устройство записи.

0 голосов
/ 05 сентября 2011
 public T Create<T> () where T : class, new()
    {
        // do what you like...

        return result ?? new T();
    }
0 голосов
/ 05 сентября 2011

Мне нравится if((result ?? 0) == 0){}

Чтобы сделать это более понятным (читаемым), вы можете определить метод расширения.

Редактировать

@ allentracks ответ точнее на ваш вопрос

...