Yuta.NET

C# 8.0の拡張メソッドを用いたenumの小技


さてさて、「C#の拡張メソッドを用いたenumの小技」で紹介した拡張メソッドですが、何と...C# 8.0を用いることでさらに簡略化できるようになりました。

ただ、C# 8.0自体はまだ普及途中な感じのため使用できる環境は限定的となりますが、面白かったので紹介します。

下記のコードは、ラムダ式を用いることで拡張メソッドを簡略化しています。他にも色々できそうですが、ここでは基本的な事を記載しています。

以前の無難な記述法


/// <summary>
/// 名称を返す
/// </summary>
/// <param name="week"><c>DayOfWeek</c></param>
/// <returns>名称</returns>
public static string ToName(this DayOfWeek week)
{
    string rtn = string.Empty;

    switch(week)
    {
        case DayOfWeek.Sunday:
            rtn = "日";
            break;
        case DayOfWeek.Monday:
            rtn = "月";
            break;
        case DayOfWeek.Tuesday:
            rtn = "火";
            break;
        case DayOfWeek.Wednesday:
            rtn = "水";
            break;
        case DayOfWeek.Thursday:
            rtn = "木";
            break;
        case DayOfWeek.Friday:
            rtn = "金";
            break;
        case DayOfWeek.Saturday:
            rtn = "土";
            break;
    }
    
    return rtn;
}

C# 8.0の記述法


/// <summary>
/// 名称を返す
/// </summary>
/// <param name="week"><c>DayOfWeek</c></param>
/// <returns>名称</returns>
public static string ToName(this DayOfWeek week) =>
    week switch
    {
        DayOfWeek.Sunday    => "日",
        DayOfWeek.Monday    => "月",
        DayOfWeek.Tuesday   => "火",
        DayOfWeek.Wednesday => "水",
        DayOfWeek.Thursday  => "木",
        DayOfWeek.Friday    => "金",
        DayOfWeek.Saturday  => "土",
        _ => throw new NotImplementedException(),
    };

下記、全文です。上手く記述することで可読性が上がりそうです。が、ラムダ式を知らない人からすると"???"って感じですね。


using System;
using System.Linq;

namespace YutaCore.ConsoleApp1
{
    /// <summary>
    /// Enum拡張メソッド用クラス
    /// </summary>
    public static class EnumExtensions
    {
        /// <summary>
        /// 名称を返す
        /// </summary>
        /// <param name="week"><c>DayOfWeek</c></param>
        /// <returns>名称</returns>
        public static string ToName(this DayOfWeek week) =>
            week switch
            {
                DayOfWeek.Sunday    => "日",
                DayOfWeek.Monday    => "月",
                DayOfWeek.Tuesday   => "火",
                DayOfWeek.Wednesday => "水",
                DayOfWeek.Thursday  => "木",
                DayOfWeek.Friday    => "金",
                DayOfWeek.Saturday  => "土",
                _ => throw new NotImplementedException(),
            };
    }

    class Program
    {
        static void Main(string[] args)
        {
            string name = string.Empty;
            // 整形用に最大文字数を取得(注:この記述のLinqは.NET3.5以上で使用可)
            int maxLength = Enum.GetNames(typeof(DayOfWeek)).Max(v => v.Length);

            // foreachでEnumの全ての列挙子(値)を取得
            foreach (DayOfWeek value in Enum.GetValues(typeof(DayOfWeek)))
            {
                // 固定幅で名称を取得
                name = string.Format("{0, -" + maxLength + "}", value.ToString());
                Console.WriteLine("{0}:{1} : {2}曜日", (int)value, name, value.ToName());
            }
            Console.ReadKey(true);
        }
    }
}