具有功能方法的枚举(组合类/枚举)

时间:2011-09-16 10:08:49

标签: c#

我可能会在这里错过某种观点,如果是这种情况 - 请将该讨论作为我问题的一部分:)。

这是一个缩短并重命名的工作代码示例。 GetTicks(…)是单个样本,可以是任何类型的功能(> 0 < 9的值应返回特定的枚举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相关的功能,尽可能接近enum本身。 enum是原因函数。此外,我发现在enum附近寻找这样的功能很容易和自然。此外,它很容易修改或扩展。

我的缺点是我必须更明确地说明enum,例如Something.TypeOf。设计可能看起来不标准?如果enum是供课堂内部使用的话,它是否适用。

你会怎样做得更好? 我尝试了abstract,基础继承,partial。它们似乎都不适用。

2 个答案:

答案 0 :(得分:73)

如果您不介意再写一些,可以使用扩展方法来扩展enum的界面。

e.g。

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 */
         }
    }
}

这可以为您的枚举添加“实例”方法。不过,它比大多数人更喜欢它。

请记住,enum应该主要作为命名值处理。

答案 1 :(得分:32)

C#enums不能像这样工作。但是,您可以非常轻松地实现自己的“固定值集”:

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。有时您甚至可能希望将类打开,但保留私有构造函数 - 这允许您仅将嵌套类创建为子类。非常方便限制继承。

缺点是你不能使用开关:(