logo

Сравнение Enum в C# и Java: адаптация Sun's Planet Enum

Быстрый ответ

Перечисления (enums) в C# фактически представляют собой именованные целочисленные значения, их идеально применять при необходимости создать список элементов:

csharp
Скопировать код
enum Colour { Red, Green, Blue }; // Здесь представлены основные цвета!

Между тем, enums в Java имеют расширенные возможности благодаря встроенным методам, полям и свойствам, это делает их аналогичными полноценным классам:

Java
Скопировать код
public enum Colour {
    RED, GREEN, BLUE;

    private static final Map<String, Colour> BY_LABEL = new HashMap<>();

    static {
        for (Colour e : values()) {
            BY_LABEL.put(e.name(), e);
        }
    }

    public static Colour valueOfLabel(String label) {
        return BY_LABEL.get(label);
    }
}

Для того чтобы наделить enums в C# аналогичными с Java функциями, можно использовать методы расширения:

csharp
Скопировать код
public enum Colour { Red, Green, Blue };

public static class ColourExtensions {
    public static string ToHex(this Colour c) {
        switch(c) {
            case Colour.Red: return "#FF0000";
            case Colour.Green: return "#00FF00";
            case Colour.Blue: return "#0000FF";
            default: throw new ArgumentOutOfRangeException(nameof(c), "Некорректный цвет, возможно, вы все еще его не открыли?");
        }
    }
}

Оглядывая Enums C#: Пользовательские атрибуты и рефлексия

Чтобы усилить функциональность enums в C# аналогично Java, сюда приходят на помощь пользовательские атрибуты и рефлексия:

csharp
Скопировать код
public enum Colour {
    [HexValue("#FF0000")] Red,
    [HexValue("#00FF00")] Green,
    [HexValue("#0000FF")] Blue
}

public class HexValueAttribute : Attribute {
    public string Value { get; }

    public HexValueAttribute(string value) {
        Value = value;
    }
}

// Для получения доступа к aтрибутам:
var hexValue = Attribute.GetCustomAttribute(typeof(Colour), typeof(HexValueAttribute)) as HexValueAttribute;
var colourHex = hexValue?.Value; // Не забывайте проверять значение на null!

Создание enums в стиле Java на C#

Enums в C# не обладают методами и свойствами, как в Java, но применение неизменяемых классов с константными readonly экземплярами переменных может стать решением:

csharp
Скопировать код
public class ColourClass {
    public static readonly ColourClass Red = new ColourClass("#FF0000");
    public static readonly ColourClass Green = new ColourClass("#00FF00");
    public static readonly ColourClass Blue = new ColourClass("#0000FF");

    public string HexValue { get; private set; }

    private ColourClass(string hex) {
        HexValue = hex;
    }
}

Такой подход эмулирует структуру Java enums, делая наборы значений похожими на классы.

Обходные пути Enums в C#: Словарь

Для упрощения можно использовать структуру данных "словарь" вместо применения пользовательских атрибутов:

csharp
Скопировать код
Dictionary<Colour, string> colourHexValues = new Dictionary<Colour, string> {
    {Colour.Red, "#FF0000"},
    {Colour.Green, "#00FF00"},
    {Colour.Blue, "#0000FF"}
};

Визуализация

В Java это выглядит следующим образом:

Java
Скопировать код
enum Tool {
    HAMMER, WRENCH, SCREWDRIVER;
}

// Набор инструментов на Java 🧰:
| Инструмент    | Описание   |
| ------------- | ---------- |
| Молоток (🔨)  | Простой    |
| Гаечный ключ (🔧) | Простой   |
| Отвертка (🔩) | Простой    |

В C# существует иной подход:

csharp
Скопировать код
enum Tool {
    HAMMER = 0,
    WRENCH = 1,
    SCREWDRIVER = 2,
    DRILL = 10 // Добавляем дрель!
}

// Набор инструментов C# 🧰✨:
| Инструмент    | Описание                                |
| ------------- | --------------------------------------- |
| Молоток (🔨)   | Простой                                 |
| Гаечный ключ (🔧) | Простой                                 |
| Отвертка (🔩) | Простой                                 |
| Дрель (🛠)     | Имеет специальное значение, выделяется из списка    |

Сравнение значений enum: Похожие подходы в C# и Java

В Java значение enum оптимально сравнивать используя ==, поскольку каждое значение представляет собой уникальный экземпляр:

Java
Скопировать код
if(day == Day.MONDAY) { /* Вставьте мотивационную фразу, чтобы поднять себе настроение в понедельник! */ }

В C#, хоть суть и та же, но важно помнить, что enum представляют собой числовые значения:

csharp
Скопировать код
if(colour == Colour.Red) { /* Весь город скоро окрасится в красный цвет! */ }

Погрузитесь в мир enum

Изучайте тему более детально, изучая статьи Джона Скита (John Skeet) о enums в C#, материалы на Codeproject о продвинутом использовании enum в C#, а также проект enum_ext на GitHub.

Тайна успеха в непрерывном обучении, экспериментировании и наличии практики!

Полезные материалы

  1. (Oracle) Типы перечислений в Java
  2. (Oracle) Рефлексия в Java
  3. (Stack Overflow) Сравнение членов enum в Java
  4. (O'Reilly) Effective Java
  5. (Microsoft) Типы перечислений в C#
  6. (Stack Overflow) Сопоставление enum со строками в C#