考虑一个具有重载索引器的二维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异常?
答案 0 :(得分:1)
如果您获得的值是意外的,并且您不知道该怎么做:抛出异常。
如果您获得的值是意外的并且您知道该怎么做:请执行此操作。
如果必须抛出异常,则抛出最有意义的异常。即。如果从业务角度(即您的类的工作),抛出自定义异常然后执行它是有意义的。否则,您可以使用通常的OutOfRangeException
。
答案 1 :(得分:1)
版本(1)是最好的。
数组double[,]
本身会抛出一个IndexOutOfRangeException
,所以我看不出自己做这个测试有什么价值。
在我看来,默默地接受无效参数(版本3)是脆弱的。
答案 2 :(得分:1)
版本1和版本2将为您提供相同的行为,因此版本1更好,因为它的代码更少。如果您要使用版本2,则还应添加空检查并在矩阵为空时抛出异常,并且可能会在版本1中执行更多检查。
版本3将隐藏您所做的任何编程错误,并且在调试时会花费您大量时间。在代码审查中,我肯定会将代码更改为版本1.