LoginSignup
13
9

More than 5 years have passed since last update.

C#のenumにフィールド・メソッドを定義したいとき【JavaからC#へ】

Last updated at Posted at 2018-08-20

コード抜粋

自分でEnum定義する方法.cs
public class AppState
{
    //フィールド一覧
    public readonly string viewStr;
    public readonly int waitTime;
    //コンストラクタ
    private AppState(string viewStr, int waitTime)
    {
        this.viewStr = viewStr;
        this.waitTime = waitTime;
    }
    //メソッド
    public string getViewStr()
    {
        return this.viewStr;
    }

    // 参照用インスタンス
    public static readonly AppState Active = new AppState("アクティブ", 10);
    public static readonly AppState Paused = new AppState("ポーズ", 20);
    public static readonly AppState Exit = new AppState("イグジット", 30);
}

はじめに

JavaのEnumでは各列挙子にフィールド・メソッドを定義できますが、C#ではできません。代わりに使える方法を探しました。
↓ Javaならこのように書きたいとき。。。

appState.java
enum AppState
{
    Active("アクティブ"), Paused("ポーズ"), Exit("イグジット");

    public final String viewStr;
    AppState(String viewStr){
        this.viewStr = viewStr;
    }
}
class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.println(AppState.Active.viewStr);    // <- enumのフィールド呼び出し
    }
}

簡易な方法:拡張メソッドを使う

C#の構文の拡張メソッドを使用すると便利です。拡張メソッドは静的メソッドをインスタンスメソッドのように呼び出せる機能です。引数のないメソッドを定義することで、実質的にフィールドを定義したように扱うこともできます。

appState.cs
public enum AppState
{
    Active, Paused, Exit
}
public static class AppStateExt
{
    private static Dictionary<AppState, string> viewStrDictionary = new Dictionary<AppState, string>()
    {
        {AppState.Active,"アクティブ" },
        {AppState.Paused,"ポーズ" },
        {AppState.Exit,"イグジット" }
    };
    public static string viewStr(this AppState state)       //<- 拡張メソッド
    {
        return viewStrDictionary[state];
    }

}
class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine(AppState.Active.viewStr());       // <- インスタンスメソッドのように呼び出せる
    }
}

この方法には弱点があります。定義したいフィールドが多いとき、フィールドの数だけDictionaryを定義するため行数が多くなりがちです。

フィールド増やした場合.cs
    private static Dictionary<AppState, string> viewStrDictionary = new Dictionary<AppState, string>()
    {
        {AppState.Active,"アクティブ" },
        {AppState.Paused,"ポーズ" },
        {AppState.Exit,"イグジット" }
    };
    private static Dictionary<AppState, int> waitTimeDictionary = new Dictionary<AppState, int>()    //<- 追加したフィールド
    {
        {AppState.Active,10 },
        {AppState.Paused,20 },
        {AppState.Exit,30 }
    };
    //(以下、フィールドの数だけ続く。。。)

多くのフィールドを扱いたいときは↓の方法をオススメします。

本格的な方法:自分でEnumを定義する

↓を参考にしたものです。

C#でタイプセーフEnumパターン
http://bleis-tift.hatenablog.com/entry/20080808/1218133517

参照用インスタンスを定義する箇所に、各インスタンスのフィールド値をまとめて記述できるので読みやすくなります。
フィールド・メソッド呼び出しもかなりJavaっぽいです。

自分でEnum定義.cs
public class AppState
{
    //フィールド一覧
    public readonly string viewStr;
    public readonly int waitTime;
    //コンストラクタ
    private AppState(string viewStr, int waitTime)
    {
        this.viewStr = viewStr;
        this.waitTime = waitTime;
    }
    //メソッド
    public string getViewStr()
    {
        return this.viewStr;
    }

    // 参照用インスタンス
    public static readonly AppState Active = new AppState("アクティブ", 10);
    public static readonly AppState Paused = new AppState("ポーズ", 20);
    public static readonly AppState Exit = new AppState("イグジット", 30);
}

class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine(AppState.Active.viewStr);         //<- フィールド呼び出し
        Console.WriteLine(AppState.Active.getViewStr());    //<- メソッド呼び出し
    }
}

参考

C# の enum に関連する小技。
https://qiita.com/tricogimmick/items/38fe86a09e8e0865d471

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9