Подтвердить что ты не робот

Enum с методами для функциональности (Combine Class/Enum)

Я могу пропустить что-то вроде этого, если это дело - включите это обсуждение в качестве части моего вопроса:).

Это сокращенный и переименованный образец рабочего кода. GetTicks (..) - это единственный образец, который может быть любой функциональностью (значение > 0 < 9 должно возвращать определенный Enum a.so).

public static class Something
{
    public enum TypeOf : short
    {
        Minute = 2, Hour = 3, Day = 4, ........
    }

    public static long GetTicks(Something.TypeOf someEnum)
    {
        long ticks = 0;
        switch (someEnum)
        {
            case Something.TypeOf.Minute:
                ticks = TimeSpan.TicksPerMinute;
                break;
            case Something.TypeOf.Hour:
                ticks = TimeSpan.TicksPerHour;
                break;
         ....
        }
        return ticks;
    }
}


// This class is called from anywhere in the system.
public static void SomeMethod(string dodo, object o, Something.TypeOf period)
{
    // With the design above
    long ticks = Something.GetTicks(period);

    // Traditional, if there was a simple enum
    if (period == Something.Day)
        ticks = TimeSpan.FromDays(1).Ticks;
    else if (period == Something.Hour)
        ticks = TimeSpan.FromHours(1).Ticks;
}

Идея состоит в том, чтобы собирать функциональные возможности, относящиеся к перечислению, как можно ближе к самому перечислению. Функция перечисления является причиной. Также мне легко и естественно искать такую ​​функциональность рядом с перечислением. Также его легко модифицировать или расширять.

Недостаток, который у меня есть, заключается в том, что я должен указать enum более явным Something.TypeOf. Дизайн может выглядеть нестандартным? и будет применяться, если перечисление предназначено для внутреннего использования в классе.

Как бы вы сделали это более приятным? Я попробовал абстрактное, базовое наследование, частичное. Ни один из них, похоже, не применяется.

4b9b3361

Ответ 1

Перечисления С# не так хорошо работают. Однако вы можете реализовать свой собственный "фиксированный набор значений" довольно легко:

public sealed class Foo
{
    public static readonly Foo FirstValue = new Foo(...);
    public static readonly Foo SecondValue = new Foo(...);

    private Foo(...)
    {
    }

    // Add methods here
}

Как это бывает, один из примеров, который я получил от этого, очень похож на ваш - DateTimeFieldType в Noda Time. Иногда вы даже можете сделать класс незапечатанным, но сохраните частный конструктор, который позволяет создавать подклассы только как вложенные классы. Очень удобно для ограничения наследования.

Недостатком является то, что вы не можете использовать переключатель: (

Ответ 2

Если вы не возражаете немного писать, вы можете сделать методы расширения для расширения интерфейса перечисления.

например.

public enum TimeUnit
{
   Second,
   Minute,
   Hour,
   Day,
   Year,
   /* etc */
}
public static class TimeUnitExtensions
{
    public static long InTicks(this TimeUnit myUnit)
    {
         switch(myUnit)
         {
           case TimeUnit.Second:
               return TimeSpan.TicksPerSecond;
           case TimeUnit.Minute:
               return TimeSpan.TicksPerMinute;
            /* etc */
         }
    }
}

Это может добавить методы экземпляра к вашим перечислениям. Хотя это немного более подробно, чем большинство из них.

Помните, что перечисление должно обрабатываться в основном как именованное значение.