16

我有这段简单的代码:

public static int GetInt(int number)
{
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue };
    foreach (int i in ints)
        if (number <= i)
            return i;

    return int.MaxValue; //this should be unreachable code since the last int is int.MaxValue and number <= int.MaxValue is allways true so the above code will allways return
}

问题是编译器说不是每个执行路径都返回一个值。所以我必须编写永远无法达到的代码。我的问题是,在这种情况下我该怎么办?我应该返回一些默认值还是应该抛出异常。另外,如果我想抛出异常,什么异常适合抛出?我没有找到类似的东西UnreachableCodeException

4

7 回答 7

27

我很想使用InvalidOperationException- 或其他一些您不会明确捕获的异常。给它一条消息,表明你真的没想到会到这里。这是一次“世界严重破碎”的失败。InvalidOperationException没有完全捕捉到这一点,但我想不出一个更好的副手。当然,您始终可以创建自己的异常以在整个代码库中使用。

不要只返回一个值,否则你永远不会知道你的世界是否颠倒了。

于 2013-06-06T15:48:25.400 回答
11

使用以下内容在您之后显示逻辑失败消息foreach

System.Diagnostics.Debug.Fail("Unreachable code reached");

这将在调试期间提醒您。

另外,在生产过程中也抛出异常:

throw new InvalidOperationException();

不要只返回一个值,尤其是一个可能有效的值:你永远不会发现逻辑错误。

于 2013-06-06T15:53:56.977 回答
5

与其从循环中返回,不如声明一个返回值变量,设置它,然后在代码末尾返回一次。

public static int GetInt(int number)
{
    var rtnVal = int.MaxValue;
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue };
    foreach (int i in ints) {
        if (number <= i) {
            rtnVal = i;
            break;
        }
    }
    return rtnVal;
}
于 2013-06-06T15:49:37.600 回答
4

我认为每种情况都不同,但是是的,最终您必须返回某些内容或抛出异常。在您的代码示例中处理此问题的方法只是从您的数组中删除 int.MaxValue :

public static int GetInt(int number)
{
    int[] ints = new int[]{ 3, 7, 9 };
    foreach (int i in ints)
        if (number <= i)
            return i;
    return int.MaxValue;
}
于 2013-06-06T15:48:09.467 回答
3

这是一个 LINQ 选项,当找不到匹配项时会自动抛出异常

public static int GetInt(int number)
{
    int[] ints = new int[]{ 3, 7, 9, int.MaxValue };
    return ints.First(i => number <= i);
}
于 2013-06-06T15:52:21.767 回答
0

为什么不只返回大于数字的第一个值

    public static int GetInt(int number)
    {
        var ints = new[] { 3, 7, 9};
        return (ints.Any(i => i > number))? 
            ints.First(i => i > number): int.MaxValue;
    }
于 2013-06-06T18:52:17.403 回答
0

编译器无法判断您的foreach循环将始终返回一个值。

理论上的编译器可以这样做,因为原则上信息是可用的,但 C# 编译器不能。

于 2013-06-06T15:47:25.380 回答