Что делать, когда я вынужден писать недостижимый код?

У меня есть этот простой кусок кода:

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.

Ответ 1

У меня возникнет соблазн использовать InvalidOperationException - или какое-то другое исключение, которое вы явно не поймаете. Дайте ему сообщение, которое указывает, что вы действительно не ожидали получить здесь. Это неудачный "мир серьезно". InvalidOperationException не совсем фиксирует это, но я не могу думать о лучшем из них. Конечно, вы всегда можете создать собственное исключение для использования на всей вашей кодовой базе.

Не просто возвращайте значение, так как иначе вы никогда не узнаете, находится ли ваш мир в обратном порядке.

Ответ 2

Используйте следующее, чтобы отобразить сообщение о сбое логики после foreach:

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

Это будет предупреждать вас во время отладки.

Кроме того, также выведите исключение во время производства:

throw new InvalidOperationException();

Не возвращайте значение, особенно потенциально допустимое: вы никогда не поймаете логическую ошибку.

Ответ 3

Вместо того, чтобы возвращаться из вашего цикла, объявите переменную возвращаемого значения, установите ее и затем верните один раз в конце кода.

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;
}

Ответ 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;
}

Ответ 5

Здесь опция LINQ, которая автоматически генерирует исключение, если совпадение не найдено

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

Ответ 6

Компилятор не может сказать, что ваш цикл foreach всегда будет возвращать значение.

Теоретический компилятор может сделать это, так как в принципе информация доступна, но компилятор С# не может.

Ответ 7

Почему бы просто не вернуть первое значение, которое больше числа вместо

    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;
    }