1

考虑一个具有重载索引器的二维 Matrix 类,如下所示:

public class Matrix
{
    private readonly double[,] _matrix;

    public double this[int i, int j]
    {
        get
        {
            return _matrix[i, j];
        }
        set
        {
            _matrix[i, j] = value;
        }
    }

    public double this[int i, int j]
    {
        get
        {
            if (i < 0 || i >= _matrix.GetLength(0) || j < 0 || j >= _matrix.GetLength(1))
                throw new IndexOutOfRangeException("index was out of range");

            return _matrix[i, j];
        }
        set
        {
            if (i < 0 || i >= _matrix.GetLength(0) || j < 0 || j >= _matrix.GetLength(1))
                throw new IndexOutOfRangeException("index was out of range");
            _matrix[i, j] = value;
        }
    }

    public double this[int i, int j]
    {
        get
        {
            if (i < 0 || i >= _matrix.GetLength(0) || j < 0 || j >= _matrix.GetLength(1))
                return 0;
            return _matrix[i, j];
        }
        set
        {
            if (i >= 0 || i < _matrix.GetLength(0) || j >= 0 || j < _matrix.GetLength(1))
                _matrix[i, j] = value;
        }
    }
}

如您所见,有 3 个版本的索引器。

1)这个版本不检查索引

2)此版本检查索引,如果它们超出尺寸范围,则抛出 IndexOutOfRangeException

3) 此版本仅在索引有效时检查索引并分配/返回值。

所以我的问题是其中哪一个是最佳实践?你更喜欢什么,为什么?或者我可以创建一个新的自定义异常,如“MatrixIndexOutOfRange”并抛出它而不是 IndexOutOfRange 异常?

4

3 回答 3

1

版本(1)是最好的。

数组double[,]本身会抛出一个IndexOutOfRangeException,所以我看不出自己做这个测试有什么价值。

在我看来,默默地接受无效参数(版本 3)很脆弱。

于 2012-09-27T08:03:11.960 回答
1

如果您获得的值是意外的并且您不知道该怎么做:抛出异常。

如果你得到的值是出乎意料的,并且你知道该怎么做:去做。

如果必须抛出异常,请尽可能抛出最有意义的异常。IE。如果从业务角度(即您的班级的工作)来看,抛出一个自定义异常是有意义的,那么就去做吧。否则,您可以正常使用OutOfRangeException.

于 2012-09-27T07:29:02.053 回答
1

版本 1 和 2 会给你相同的行为,所以版本 1 更好,因为它的代码更少。如果您选择版本 2,您还应该添加一个空检查并在矩阵为空时抛出异常,并且可能更多的检查将在版本 1 中失败。

第 3 版只会隐藏您犯的任何编程错误,并且会在调试时花费您大量时间。在代码审查中,我肯定会将代码更改为版本 1。

于 2012-09-27T08:09:31.083 回答