Предварительные условия контракта в конструкторе пустого тела - PullRequest
8 голосов
/ 31 марта 2011

Доброе утро! Я пишу класс для рисования гистограмм и для удобства пользователей решил добавить несколько удобных конструкторов.

Однако, как только я недавно переключился на контракты с кодом .NET от DevLabs, я хочу в полной мере использовать предварительные условия для защиты от собственной (или чьей-либо) глупости.

    public HistoGrapher(IList<string> points, IList<T> values)
        : this(points.Select((point, pointIndex) => new KeyValuePair<string, T>(point, values[pointIndex])))
    {
        Contract.Requires<ArgumentNullException>(points != null, "points");
        Contract.Requires<ArgumentNullException>(values != null, "values");
        Contract.Requires<ArgumentException>(points.Count == values.Count, "The lengths of the lists should be equal.");
    }

    public HistoGrapher(IEnumerable<KeyValuePair<string, T>> pointValuePairs)
    {
        // useful code goes here
    }

Есть вещь, которая смущает меня. Я не хочу, чтобы первый конструктор когда-либо вызывал второй, если контракт нарушен; однако предполагается, что вызов this(...) будет выполнен до выполнения тела первого конструктора.

Будет ли этот код работать так, как я хочу? Я еще не пробовал. А если нет, то есть ли возможность решить такую ​​проблему?

1 Ответ

5 голосов
/ 31 марта 2011

А если нет, то есть ли возможность решить такую ​​проблему?

Поскольку тело конструктора выполняется только после вызова другого конструктора, я неЯ думаю, что ваш нынешний подход может работать.Я бы порекомендовал выделить общий код в отдельный метод, т. Е. Init(), который затем можно вызвать из обоих конструкторов, что сделает ваш код СУХИМЫМ и решит вашу проблему:

public class HistoGrapher
{

    public HistoGrapher(IList<string> points, IList<T> values)
    {
        Contract.Requires<ArgumentNullException>(points != null, "points");
        Contract.Requires<ArgumentNullException>(values != null, "values");
        Contract.Requires<ArgumentException>(points.Count == values.Count, "The lengths of the lists should be equal.");

        var pointValuePairs = points.Select((point, pointIndex) => new KeyValuePair<string, T>(point, values[pointIndex]))
        Init(pointValuePairs);
    }

    public HistoGrapher(IEnumerable<KeyValuePair<string, T>> pointValuePairs)
    {
        Init(pointValuePairs);
    }

    private void Init(IEnumerable<KeyValuePair<string, T>> pointValuePairs)
    {
         // useful code goes here
    }
}
...