web-dev-qa-db-ja.com

C#switchステートメントのデフォルトラベルは、null許容列挙型をどのように処理しますか?

C#switchステートメントのデフォルトラベルは、null許容列挙型をどのように処理しますか?

デフォルトのラベルはヌルと未処理のケースをキャッチしますか?

53
Trey Mack

Nullの場合、デフォルトのラベルにヒットします。

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を出力します。

79
Trey Mack

Null結合演算子??を使用して、nullスイッチ値を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;
        }
    }
}
1
Glenn Slayden