39

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.

Sae1962
1,2981 gold badge17 silver badges33 bronze badges
asked Sep 16, 2011 at 10:08

2 Answers 2

74

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.

Sae1962
1,2981 gold badge17 silver badges33 bronze badges
answered Sep 16, 2011 at 13:56
Sign up to request clarification or add additional context in comments.

4 Comments

How do you tie 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.
@DavidHarkness, it's because of the "this" in this line: public static long InTicks(this TimeUnit myUnit). The "this" associate TimeUnit to extension.
I like Jon's answer, but this is a possibility as well. +1, I hadn't considered Extension methods for this!
This one combines the fastness of enums with the elegance of extension methods. Too bad there aren't extension properties. ☹
32

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 :(

James McMahon
49.8k69 gold badges212 silver badges288 bronze badges
answered Sep 16, 2011 at 10:14

9 Comments

Fully indeed, ramarkably alike! I like your approach and will dig into it later when I can aware time for optimize and understand it's benefits (if some) ;)).
Yeah, Java-like enums. Though I'd recommend using a structure, not a class. And a Value field for fast comparing and the switch statement.
@Andrei: True. I'd probably write a unit test to verify it with reflection :)
Why would one use this accepted answer's approach over providing extension methods to the Enum class? I am just wondering for my own knowledge. It seems to offer the exact same functionality.
@RichieEpiscopo: With the enum, you'd still only have that single value. So implementing those extension methods may well be a pain; you can't use any of the normal OO techniques, or have any state etc.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.