I may miss some sort of point here, if that's the case - please include that discussion as a part of my question :).
This is a shortened down and renamed sample of a working code. The GetTicks(…)
is a single sample, which could be any sort of functionality (value of > 0 < 9
should return a specific 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; }
The idea is to collect functionality that concerns an enum
, near as possible to the enum
itself. The enum
is the reason function. Also, I find it easy and natural to look for such functionality near the enum
. Also, it's easy to modify or extend.
The drawback I have is that I have to state the enum
more explicit, like Something.TypeOf
. The design may look non-standard? And would it apply, if the enum
was for internal use in the class.
How would you do this more nicely? I tried abstract
, base inheritance, partial
. None of them seem to apply.
The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.
An enum just spills its contents into the enclosing scope, and is basically a const static integer. This means that the first element of any default enum is the same using the == operator. Enum classes have their own scope, and don't pollute the namespace that they are in.
Since Kotlin enums are classes, they can have their own properties, methods, and implement interfaces.
Enums cannot inherit from other enums. In fact all enums must actually inherit from System. Enum . C# allows syntax to change the underlying representation of the enum values which looks like inheritance, but in actuality they still inherit from System.
If you don't mind a little more writing you can make extension methods to expand the interface of the 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 */ } } }
This can add "instance" methods to your enums. It's a bit more verbose than mostly liked, though.
Remember though that an enum
should be treated mostly as a named value.
C# enums don't work well like this. However, you can implement your own "fixed set of values" fairly easily:
public sealed class Foo { public static readonly Foo FirstValue = new Foo(...); public static readonly Foo SecondValue = new Foo(...); private Foo(...) { } // Add methods here }
As it happens, one example I've got of this is remarkably similar to yours - DateTimeFieldType
in Noda Time. Sometimes you might even want to make the class unsealed, but keep the private constructor - which allows you to create subclasses only as nested classes. Very handy for restricting inheritance.
The downside is that you can't use switch :(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With