10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C# と Java の列挙型の違い

Posted at

C# と Java の列挙型の違い

はじめに

某イベントで Effective Java の訳者として有名な柴田さんとお話する機会があり、長年の疑問が解決したのでメモ。

それぞれの列挙型

C# の場合

C# の列挙型はとてもシンプルです。C 言語の enum と同じです。

public enum Gender
{
    NotKnown = 0,
    Male = 1,
    Female = 2,
    NotApplicable = 9
}

こんなかんじで使えます。

if (customer.Gender == Gender.Female)
{
    // 女性の場合は割引金額
    return 1500;
}

return 1800;

整数で書くと if (customer.Gender == 2) のようになるので、仕様書をひっくり返して 2 ってなんだっけ? ってなりますね。列挙型のおかげでいろいろ助かるわけです。

Java の場合

Java の列挙型は C# のそれと比較して強力です。後発の C# の方が Java より強力であることのほうが多いのですが、列挙型は Java の方が強力な機能の一つです。

public enum Gender {
    NotKnown(0, "不明"),
    Male(1, "男性"),
    Female(2, "女性"),
    NotApplicable(9, "判別不能");

    private final int id;
    private final String name;

    private Gender(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getFee() {
        if (this.equals(Gender.Female)) {
            // 女性の場合は割引
            return 1500;
        }
        return 1800;
    }

    @Override
    public String toString() {
        return this.name;
    }
}

C# と違い、Java の列挙型はクラスそのものです。C# では料金を性別で切り替えるのを列挙型の外に書きましたが、Java では列挙型の中に書けます。

こういう区分で処理を切り替えることはよくありますが、C# のような単純な列挙型の場合は、処理の切り替えを探すのが一苦労です。Java の用に列挙型に書ければ、すぐに見つかるわけですね。

なんで C# の列挙型はしょぼいの?

できないものはしょうがないのであまり調べたことはなかったんですが、柴田さんから納得できる理由をもらいました。

C# は 1.0 (2002) の時点で列挙型は組み込まれていました。対する Java はと言うと... その時点では列挙型がなかったんですね。つまり列挙型に関しては Java の方が後発で、C# よりいい仕様を取り入れることができたってことのようです。

ちなみに、Java への列挙型の導入は Java 5.0 (2004) からです。

よくよく考えると、高機能な列挙型があるのにもかかわらず、よく使われる Calendar.DAY_OF_MONTH などは全て整数で列挙型ではありません。その頃にはなかったんですね。全く気が付きませんでした。

おまけ

C# でも対抗はできる

C# の (厳密には .NET の) 列挙型はオブジェクトではないので、Java と同じにはなりません。しかし、拡張メソッドを使うと同じようなことはできます。

public static class GenderExtensions
{
    public int GetFee(this Gender gender)
    {
         if (gender == Gender.Female)
         {
             return 1500;
         }
         return 1800;
    }
}

このクラスを Gender 列挙型と同じ名前空間で同じファイルに書けば Java とあんまりかわりません!

ただ、ToString() メソッドとかはこの方法が使えないんですよね...

そもそも必要なの?

確かに Java の列挙型は便利なんですけど、ないならないでっていうお話も。

処理が複雑な場合はストラテジーパターン (もしくはステートパターン) を利用したほうがすっきりするのはよく知られています。

また、金額をデータベースから読み込みたいとなると列挙型には書きづらくなります。

ないならないでなんとかなるんです。

でも、ちょっとした列挙型とか書くときは Java が羨ましくなるのでした!

10
3
5

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
10
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?