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.
2 Answers 2
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.
4 Comments
TimeUnitExtensions
to TimeUnit
and the TimeSpan
instance for which you want the ticks? I may be missing some context and no doubt my lack of C# knowledge isn't helping.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 :(