空体构造函数中的合同前置条件

时间:2011-03-31 14:36:55

标签: c# .net constructor code-contracts

早上好!我正在编写一个用于绘制直方图的类,为了方便用户,我决定添加一些便利构造函数。

但是,一旦我最近从DevLabs切换到.NET代码合同,我想充分利用前提条件来防止我自己(或某人)的愚蠢。

    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 个答案:

答案 0 :(得分:5)

  

如果没有,是否有能力   解决这个问题?

由于构造函数体仅在调用其他构造函数后执行,我认为您当前的方法不起作用。我建议将公共代码分解为一个单独的方法,即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
    }
}