Лучшие практики использования контрактов кода

У меня есть несколько вопросов относительно контрактов кода и лучших практик их использования. Допустим, у нас есть класс с несколькими свойствами (см. пример ниже):

class Class1
{
    // Fields
    private string _property1;       //Required for usage
    private List<object> _property2; //Not required for usage

    // Properties
    public string Property1 
    { 
        get
        {
            return this._property1;
        }            
        set
        {
            Contract.Requires(value != null);
            this._property1 = value;
        } 
    }
    public List<object> Property2 
    { 
        get
        {
            return this._property2;
        }
        set
        {
            Contract.Requires(value != null);
            this._property2 = value;
        }
    }

    public Class1(string property1, List<object> property2)
    {
        Contract.Requires(property1 != null);
        Contract.Requires(property2 != null);

        this.Property1 = property1;
        this.Property2 = property2;
    }

    public Class1(string property1)
        : this(property1, new List<object>())
    { }
}

Некоторые пояснения о том, чего я хочу добиться:

(a) свойство1 является обязательным полем. свойство2 явно не требуется для нормального использования объекта.

У меня есть следующие вопросы:

  1. Стоит ли мне вообще возиться с контрактами для property2; поскольку property2 не является обязательным полем, должен ли у него вообще быть контракт. Указывает ли размещение контракта на property2, что оно действительно требуется для нормального использования объекта;

  2. Даже если property2 явно не является обязательным, нет никаких возможных причин для того, чтобы оно было нулевым, поэтому определен контракт в сеттере. Разве определение контракта на property2 не уменьшит количество проверок на null в вызывающем коде? Это должно уменьшить количество ошибок и улучшить сопровождаемость кода - верно ли это предположение?

  3. Если верно, то как мне гарантировать вызывающему коду, что property2 никогда не будет равно null? Использую ли я Contract.Invariant(property2 != null); или Contract.Ensures(property2 != null) в конструкторе, или Contract.Ensures(property2 != null) в Init(), или Contract.Ensures(property != null) в сеттере? (т.е. если используется Contract.Ensures(property2 != null), то где он размещается)?

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

7
задан ThinkingStiff 10 March 2013 в 04:44
поделиться