4

在我的游戏中,检查了很多东西,而且索引经常超出范围,如果有时没有绘制或检查东西通常是可以的。目前我的代码很容易阅读,但在调试时,由于正在记录的异常,游戏会丢失一两帧。不过,它在 VS 之外也能正常工作。当我尝试使用大量if语句来避免异常情况时,它大大降低了代码的可读性并消除了低 fps 损失。我想知道它是否还有其他影响。

4

4 回答 4

7

抛出异常是非常耗费资源的——使用 if/then 语句或其他“正常”流控制要快得多。

异常主要是昂贵的,因为生成异常实例需要执行堆栈遍历来确定异常被抛出的位置(堆栈跟踪)。它还为垃圾收集器创建了额外的负载,并且被认为是非常糟糕的设计,无法在异常情况之外使用异常。

于 2012-07-16T02:29:51.050 回答
4

可以使用很多trys 而不是更多ifs 吗?

如果您需要其中任何一个来实现功能性应用程序,那么您的设计可能有问题。异常情况通常被认为是异常的,而不是司空见惯的。

您描述的情况(索引超出范围)显然不是例外,特别是因为您忽略了例外,因为这没什么大不了的。这是一个很大的暗示,您应该首先投入精力防止异常发生。

当我试图使用大量的 if 语句来避免异常情况时......

正如您所发现的,大量if语句不是一个好方法——它很难阅读,而且它可能会隐藏逻辑错误,这只会带来更多的麻烦。

相反,请考虑为您的对象赋予更明确定义和离散的职责,以防止它们进入可能一开始就异常的状态。如果您需要“很多很多”if语句,那么您的对象正在检查许多条件,这意味着它们的职责可能太大了。

于 2012-07-16T02:31:38.747 回答
2

通常,您应该编写代码并构建逻辑,以便不使用异常来处理程序逻辑。在某些情况下,可以使用异常来处理罕见预期的情况。但是,控制流应该避免异常,因为它们基本上goto是可以使控制流非常混乱的语句,并且它们不是高性能的。

在您的情况下,使用异常处理逻辑错误听起来并不合适。事实上,这些例外听起来就像他们正在做他们应该做的事情。也就是说,他们告诉你你的算法是错误的。

我建议仔细查看您的代码,并确定您的代码为什么会抛出IndexOutOfBoundsException. 如果它在您自己的参数的内部处理过程中被抛出,您可能遇到了错误或设计不佳的算法。问:“这个索引是从哪里来的?” “有没有办法编写算法,以便在设计中建立界限而不是事后才添加?”

于 2012-07-16T02:30:44.487 回答
0

您应该始终编写代码以避免异常。捕获它们的成本非常高。

您还应该避免大量嵌套if语句。你是对的,它们使你的代码可读性降低。

您可能会发现switch语句会有所帮助,但还有许多其他方法可以避免异常和if语句。

例如,您可以编写此扩展方法:

public static class Ex
{
    public static void IfBounded<T>(this T[] @this, int index, Action<T> action)
    {
        if (@this == null) throw new System.ArgumentNullException("@this");
        if (action == null) throw new System.ArgumentNullException("action");
        if (index >= @this.GetLowerBound(0) && index <= @this.GetUpperBound(0))
        {
            action(@this[index]);
        }
    }
}

现在您可以编写以下类型的代码:

var messages = new []
{
    "Hello",
    "Goodbye",
};

messages.IfBounded(-1, t => Console.WriteLine(t));
messages.IfBounded(0, t => Console.WriteLine(t));
messages.IfBounded(1, t => Console.WriteLine(t));
messages.IfBounded(2, t => Console.WriteLine(t));

这种特定的扩展方法可能不适合您的情况,但是这样的事情可以使您的代码非常简洁明了。

于 2012-07-16T02:33:12.707 回答