IndexOutOfRangeException (C#) 与 ArrayIndexOutOfBoundsException(Java)

Posted

技术标签:

【中文标题】IndexOutOfRangeException (C#) 与 ArrayIndexOutOfBoundsException(Java)【英文标题】:IndexOutOfRangeException (C#) vs ArrayIndexOutOfBoundsException(Java) 【发布时间】:2021-05-10 23:57:08 【问题描述】:

我只是在为我的一个朋友实现一个很酷且简单的棋盘(棋盘风格)游戏。 由于他希望游戏在 android 和 Windows 桌面上运行,我正在使用 java 实现 Android Studio 中的 android 版本和 VS2019 C# .NET 中的 Windows 桌面版本。

我现在正在尝试将以下 java 异常移植到 C# .NET;这是java代码:

package eu.georgtoth.game.exceptions;

import eu.georgtoth.game.constants.BOARDCOLUMN;
import java.lang.ArrayIndexOutOfBoundsException;
import java.lang.IndexOutOfBoundsException;
/**
 * BoardIndexOutOfBoundsException extends @link ArrayIndexOutOfBoundsException
 * thrown, when column @link BOARDCOLUMN and row @link Integer are out of board bounces!
 */
public class BoardIndexOutOfBoundsException extends ArrayIndexOutOfBoundsException 
    /**
     * constructor with message calling super ctor @link ArrayIndexOutOfBoundsException(String s)
     * @param message @link String for exception message
     */
    public BoardIndexOutOfBoundsException(String message)  super(message); 

    /**
     * constructor with message and inner exception using @link #initCause(Throwable throwable)
     * @param message @link String detailed exception message
     * @param throwable @link Throwable for inner exception 
     */
    public BoardIndexOutOfBoundsException(String message, Throwable throwable) 
        this(message);
        super.initCause(throwable);
    

    /**
     * constructor with board column and row indexer, calling base ctor 
     *   with inner exception (@link IndexOutOfBoundsException) as Throwable @link Throwable
     * @param column board @link BOARDCOLUMN column indexer
     * @param row    board @link Integer row indexer
     */
    public BoardIndexOutOfBoundsException(BOARDCOLUMN column, int row) 
        this("board accessor out of bounce at field: " + column.getName() + row,
            ((IndexOutOfBoundsException) 
                (new Throwable("out of bounds at colunn=" + column.getValue() + ", row=" + row))));
    

https://docs.oracle.com/javase/9/docs/api/java/lang/ArrayIndexOutOfBoundsException.html https://docs.oracle.com/javase/9/docs/api/java/lang/IndexOutOfBoundsException.html

我有以下问题/疑问:

    C#中没有具体的ArrayIndexOutOfSomeWhatException,只有IndexOutOfRangeException。

    IndexOutOfRangeException 是一个密封的(某种框架)类,不能被继承。

    但 .NET 中还有另一个“出于某种原因”异常,称为 ArgumentOutOfRangeException

我仍然不能完全理解在 Exception 子类树中具有许多类似兄弟(叶节点)的 .NET 异常的某种更扁平的层次结构。 (使用 C# .NET 8 年后的悲剧)

谁能解释一下,什么时候应该使用IndexOutOfRangeException,什么时候ArgumentOutOfRangeException在语义上是正确的?

在这种情况下,什么是语义上正确的选择?

在没有派生类的情况下调用简单的IndexOutOfRangeException。 (看起来不像时髦的代码)? 调用简单的ArgumentOutOfRangeException? 实现从ArgumentOutOfRangeException派生的框架子类?

亲切的问候,海因里希。

ps:我知道这个问题是一个迂腐的怪癖,但我真的不明白这里的确切形式差异。 (通常在时间紧迫的工作中,我会在与同事协商(投票或老板确定)后实施一些变体,但与 Java 相比,.NET 的异常层次结构对我来说并不完全可以理解。

【问题讨论】:

IndexOutOfRangeException 如果使用无效索引值访问数组元素,则主要由框架抛出。如果你想根据用户输入的 ChessBoard 坐标抛出异常,你应该抛出 ArgumentOutOfRangeException 或者可能是你自己继承自 ArgumentOutOfRangeException 的异常。 【参考方案1】:

IndexOutOfRangeException 适用于当您尝试访问索引超出范围的数组或集合的元素时。例如,访问大小为 10 的数组的第 11 个元素。

ArgumentOutOfRangeException 不涉及数组。当值超出范围时使用它。例如,将某人的生日设置为第 13 个月。

你应该扩展哪个? Board index out of bounds 听起来有点像有人试图用超出范围的索引来定位某些东西。似乎 IndexOutOfRangeException 是一个合理的选择。但是,它扩展了 SystemException,这可能不适合您的应用程序的异常。

你有什么理由不只是扩展 Exception 吗?这似乎是微软的文档所暗示的: https://docs.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions

他们的最佳实践文档建议尽可能使用内置异常。 IndexOutOfRangeException 不适合您吗? https://docs.microsoft.com/en-us/dotnet/standard/exceptions/best-practices-for-exceptions

【讨论】:

以上是关于IndexOutOfRangeException (C#) 与 ArrayIndexOutOfBoundsException(Java)的主要内容,如果未能解决你的问题,请参考以下文章

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?

什么是 IndexOutOfRangeException / ArgumentOutOfRangeException,我该如何解决?

IndexOutOfRangeException (C#) 与 ArrayIndexOutOfBoundsException(Java)