Неловкое выглядящее использование Контракта. ValueAtReturn ()

Я разрабатываю метод, который добавит элемент к внутреннему списку. Структура класса - что-то вроде:

class MyCustomerDatabase {
    private IList<Customer> _customers = new List<Customer>();

    public int NumberOfCustomers { get { return _customers; } }    

    public void AddCustomer(Customer customer) {
        _customers.Add(customer);
    }
}

Теперь, я думал о добавлении a Contract.Ensures() о размере _customers, растущего на 1 с этим вызовом. Проблема состоит в том, что я заканчиваю с некоторым странно выглядящим кодом:

public void AddCustomer(Customer customer) {
    int numberOfCustomersAtReturn;
    Contract.Ensures(Contract.ValueAtReturn<int>(out numberOfCustomersAtReturn) == 
Contract.OldValue<int>(NumberOfCustomers) + 1);


    _customers.Add(customer);
    numberOfCustomersAtReturn = NumberOfCustomers;
}

Основная проблема состоит в том, что свойства являются на самом деле методами, таким образом, Вы не можете просто сослаться на них direcly при использовании Contract.ValueAtReturn() поскольку его единственный параметр принимает переменные как out. Ситуация становится еще более странной, если я хочу достигнуть того же, но на этот раз с методом, который должен возвратить значение:

public int MyReturningMethod() {
    ...
   return abc(); //abc will add by one the number of customers in list
}
//gets converted to
public int MyReturningMethod() {
    int numberOfCustomersAtReturn;
    Contract.Ensures(Contract.ValueAtReturn<int>(out numberOfCustomersAtReturn) == Contract.OldValue<int>(NumberOfCustomers) + 1);

    int returnValue = abc();
    numberOfCustomersAtReturn = NumberOfCustomers;
    return returnValue;
}

Это кажется довольно неуклюжим :(

Контракты кода должны иметь целью получать более ясные вещи, и это кажется правильным противоположное. Я делаю что-то не так?

Спасибо

1
задан Jon Seigel 9 May 2010 в 04:58
поделиться

2 ответа

Кажется, что вы переусложняете вещи без причины. ValueAtReturn используется для обсуждения out параметров метода, и ничего больше - а у вас нет никаких out параметров!

То, что вы ищете, это OldValue.

Предполагая, что эта строка:

public int NumberOfCustomers { get { return _customers; } }   

должна быть:

public int NumberOfCustomers { get { return _customers.Count; } }

Все, что вам нужно сделать:

class MyCustomerDatabase
{
    private readonly IList<Customer> customers = new List<Customer>();

    public int NumberOfCustomers { get { return customers.Count; } }

    public void AddCustomer(Customer customer)
    {
        Contract.Ensures(NumberOfCustomers ==
                         Contract.OldValue(NumberOfCustomers) + 1);

        customers.Add(customer);
    }
}

Статическая проверка может доказать это просто отлично, благодаря постусловиям в IList :)

1
ответ дан 3 September 2019 в 00:45
поделиться

Думаю, вы все делаете правильно.

Хотя мне кажется, что вы доводите Contracts до крайности, описывая точные последствия вызова этого метода для вывода. Imho основная идея контрактов заключалась в том, чтобы гарантировать базовые гарантии, такие как положительные, вообще возвращающие значение и так далее.

1
ответ дан 3 September 2019 в 00:45
поделиться
Другие вопросы по тегам:

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