Как метка по умолчанию оператора switch в C # будет обрабатывать перечисление, допускающее значение NULL?

Как метка по умолчанию оператора switch в C # будет обрабатывать перечисление, допускающее значение NULL?

Будет ли метка по умолчанию ловить нули и любые необработанные случаи?


person Trey Mack    schedule 19.02.2013    source источник
comment
Спецификация языка C #, 8.7.2 Оператор switch. msdn.microsoft.com/en-us/library/ms228593.aspx   -  person Dennis    schedule 19.02.2013


Ответы (3)


Если он нулевой, он попадет в метку по умолчанию.

public enum YesNo
{
    Yes,
    No,
}

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = null;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

Программа напечатает default.

Если не обрабатывается null.

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = null;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            case null:
                Console.WriteLine("NULL");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

печатает NULL.

Если у вас есть необработанное значение перечисления, которое было добавлено позже:

public enum YesNo
{
    Yes,
    No,
    FileNotFound,
}

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = YesNo.FileNotFound;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

Он по-прежнему печатает default.

person Trey Mack    schedule 19.02.2013
comment
Это одна из причин, почему мне нравится C # больше, чем Java. - person Hirofumi Okino; 11.08.2016

Вы можете использовать оператор объединения с нулем ??, чтобы направить null значения переключателя в конкретную метку case, отличную от default:

public static IEnumerable<String> AsStrings(this IEnumerable<Char[]> src)
{
    Char[] rgch;

    var e = src.GetEnumerator();
    while (e.MoveNext())
    {
        switch ((rgch = e.Current)?.Length ?? -1)
        {
            case -1:    // <-- value when e.Current is 'null'
                yield return null;
                break;
            case 0:
                yield return String.Empty;
                break;
            case 1:
                yield return String.Intern(new String(rgch[0], 1));
                break;
            default:   // 2...n
                yield return new String(rgch);
                break;
        }
    }
}
person Glenn Slayden    schedule 18.09.2016

Стоит упомянуть, что C # 8.0 представил новый шаблон свойств для выражения переключения. Теперь вы можете реализовать логику переключения по умолчанию, используя подчеркивание:

public double Calculate(int left, int right, Operator op) =>
    op switch 
{
    Operator.PLUS => left + right,
    Operator.MINUS => left - right,
    Operator.MULTIPLY => left * right,
    Operator.DIVIDE => left / right,
    _    =>  0 // default
}

Ref. https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

person Przemek Struciński    schedule 09.10.2019
comment
Для этого выражения переключения вы должны добавить ветвь по умолчанию, здесь это не обязательно. (Как еще компилятор может убедиться, что выражение всегда возвращает значение?) - person Hans Kesting; 24.03.2021