Как заключить Кодовые контракты, что переменная не равна нулю?

У меня есть метод factory

    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 считают, что varible может быть нулевым, и нет способа доказать, что 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: assert unproven

Я попробовал make check для null, и это заставило все предупреждения уйти:

    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;
    }

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

Спасибо.

Ответ 1

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

Contract.Assume(result != null);

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

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

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

Ответ 2

Как if((result ?? 0) == 0){}

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

Edit

@allentracks ответ более точный для вашего вопроса

Ответ 3

 public T Create<T> () where T : class, new()
    {
        // do what you like...

        return result ?? new T();
    }