具有两个索引参数的方法,其中有效范围相互依赖:ArgumentOutOfRangeException 或 ArgumentException?
Method with two index parameters, where valid range interdependent: ArgumentOutOfRangeException OR ArgumentException?
考虑以下场景:
一个方法期望两个索引被确定为参数,并且其中一个等于或大于另一个,使得有效范围相互依赖。
例如,获取数组子副本的方法,具有开始和结束索引:
public static T[] Sub<T>(this T[] @this, int start, int end) {
//Somewhere within...
var newLength = end - start;
if (newLength < 0)
//Throw exception because end<start...
}
现在,这是(诚然有点无关紧要,但仍然很有趣 [恕我直言])的问题:
ArgumentOutOfRangeException
定义为:
The exception that is thrown when the value of an argument is outside
the allowable range of values as defined by the invoked method.
哪个适合这个场景,哪个不适合:
- 该方法定义了"index A must be less than index B",但是定义了
A
和[=13之间的关系=];不完全是 A
和 B
... 的 有效范围
- 最终,在本例中,
B
的有效范围由A
定义;不是(明确地)通过方法。
另一方面,ArgumentException
定义为:
The exception that is thrown when one of the arguments provided to a
method is not valid.
考虑到我关于 B
的有效范围如何由 A
定义的论点,实际上完全符合:
- 一个参数
B
在小于 A
. 时 无效
然而,异常(不管是哪个)仍然基于 index,并直接与有效或无效的 ranges 相关联如果索引...
所以...
是否应该抛出更一般的 ArgumentException
,因为它是使它们无效的索引组合?
是否应该抛出更具体的 ArgumentOutOfRangeException
,即使这里的 "invalidity" 没有(?)相当 匹配异常的预期用途?
还是应该 SomethingElseEntirelyException
被抛出?
我会选择 ArgumentOutOfRangeException
。这与框架中其他地方的其他示例相吻合:
string.Substring(int, int)
如果“startIndex 加上 length 表示位置不在该实例中,则 AOORE
抛出。”
Array.Copy(Array, int, Array, int, int)
如果“sourceIndex 小于 sourceArray[=49= 的第一个维度的下限,则抛出 AOORE
]."
DateTime(int, int, int)
如果“day 小于 1 或大于 month[=49 中的天数,则抛出 AOORE
=]."
另一方面,我也应该举个反例:
Stream.Read(byte[], int, int)
抛出 ArgumentException
如果 "The sum of offset and count is larger than the buffer length."
我不确定为什么最后一个是这样定义的,但我想说该方法根据其他方法定义有效值范围是合理的参数和对象的状态。不过,我个人会尝试根据 较早的 参数来定义特定参数的有效值范围 - 所以如果您有 Foo(int x, int y)
并且要求 x < y
, 那么我会说 y
的有效范围是根据 x
.
定义的
考虑以下场景:
一个方法期望两个索引被确定为参数,并且其中一个等于或大于另一个,使得有效范围相互依赖。
例如,获取数组子副本的方法,具有开始和结束索引:
public static T[] Sub<T>(this T[] @this, int start, int end) {
//Somewhere within...
var newLength = end - start;
if (newLength < 0)
//Throw exception because end<start...
}
现在,这是(诚然有点无关紧要,但仍然很有趣 [恕我直言])的问题:
ArgumentOutOfRangeException
定义为:
The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method.
哪个适合这个场景,哪个不适合:
- 该方法定义了"index A must be less than index B",但是定义了
A
和[=13之间的关系=];不完全是A
和B
... 的 有效范围
- 最终,在本例中,
B
的有效范围由A
定义;不是(明确地)通过方法。
另一方面,ArgumentException
定义为:
The exception that is thrown when one of the arguments provided to a method is not valid.
考虑到我关于 B
的有效范围如何由 A
定义的论点,实际上完全符合:
- 一个参数
B
在小于A
. 时 无效
然而,异常(不管是哪个)仍然基于 index,并直接与有效或无效的 ranges 相关联如果索引...
所以...
是否应该抛出更一般的 ArgumentException
,因为它是使它们无效的索引组合?
是否应该抛出更具体的 ArgumentOutOfRangeException
,即使这里的 "invalidity" 没有(?)相当 匹配异常的预期用途?
还是应该 SomethingElseEntirelyException
被抛出?
我会选择 ArgumentOutOfRangeException
。这与框架中其他地方的其他示例相吻合:
string.Substring(int, int)
如果“startIndex 加上 length 表示位置不在该实例中,则AOORE
抛出。”Array.Copy(Array, int, Array, int, int)
如果“sourceIndex 小于 sourceArray[=49= 的第一个维度的下限,则抛出AOORE
]."DateTime(int, int, int)
如果“day 小于 1 或大于 month[=49 中的天数,则抛出AOORE
=]."
另一方面,我也应该举个反例:
Stream.Read(byte[], int, int)
抛出ArgumentException
如果 "The sum of offset and count is larger than the buffer length."
我不确定为什么最后一个是这样定义的,但我想说该方法根据其他方法定义有效值范围是合理的参数和对象的状态。不过,我个人会尝试根据 较早的 参数来定义特定参数的有效值范围 - 所以如果您有 Foo(int x, int y)
并且要求 x < y
, 那么我会说 y
的有效范围是根据 x
.