Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Enum with Pair Values like dictionary

Tags:

c#

.net

In c# I'm a little puzzled to understand Enum.

In my specif case I would need store constant value in a Name Value format like>

300 seconds = 5 minutes

At the moment I use this class.

  • Would be possible to use Enum instead, so I the Enum class would look likes?
  • Can I store in an Enum a Pair Values?

Could you provide me a sample of code?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MyWebSite.Models
{
    public class Reminders
    {
        private sortedDictionary<int, string> remindersValue = new SortedDictionary<int, string>();

        // We are settign the default values using the Costructor
        public Reminders()
        {
            remindersValue.Add(0, "None");
            remindersValue.Add(300, "5 minutes before");
            remindersValue.Add(900, "15 minutes before");
        }

        public SortedDictionary<int, string> GetValues()
        {
            return remindersValue;
        }

    }
}
like image 531
GibboK Avatar asked Jan 21 '13 09:01

GibboK


4 Answers

You could use a Tuple<int, int> as dictionary key( at least with .NET >= 4 ).

But since you actually want to store a TimeSpan, use that as key.

private static Dictionary<TimeSpan, string> TimeSpanText = new Dictionary<TimeSpan, string>();

static Reminders()
{
    TimeSpanText.Add(TimeSpan.Zero, "None");
    TimeSpanText.Add(TimeSpan.FromMinutes( 5 ), "5 minutes before");
    TimeSpanText.Add(TimeSpan.FromMinutes( 15 ), "15 minutes before");
    TimeSpanText.Add(TimeSpan.FromMinutes( 30 ), "30 minutes before");
    TimeSpanText.Add(TimeSpan.FromHours( 1 ), "1 hour before");
    // ....
}

public static string DisplayName(TimeSpan ts)
{
    string text;
    if (TimeSpanText.TryGetValue(ts, out text))
        return text;
    else
         throw new ArgumentException("Invalid Timespan", "ts");
}

You can get the translation in this way:

var quarter = TimeSpan.FromMinutes(15);
string text = TimeSpanText[ quarter ];
like image 168
Tim Schmelter Avatar answered Nov 03 '22 13:11

Tim Schmelter


You can decorate your enumeration with description attributes and access them later through reflection. For example,

enum ReminderTimes
{
    [Description("None")]
    None = 0,

    [Description("5 minutes before")]
    FiveMinutesBefore = 300,

    [Description("15 minutes before")]
    FifteenMinutesBefore = 900
}

You can get the description by:

public static string GetDescription(this Enum value)
{            
    FieldInfo field = value.GetType().GetField(value.ToString());

    DescriptionAttribute attribute
            = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
                as DescriptionAttribute;

    return attribute == null ? value.ToString() : attribute.Description;
}

See also: http://www.codeproject.com/Articles/13821/Adding-Descriptions-to-your-Enumerations

like image 40
lc. Avatar answered Nov 03 '22 14:11

lc.


An enum is actually a named integer type. E.g.

public enum Foo : int 
{
   SomeValue = 100,
}

which means that you create a Foo enumeration with the type 'int' and some value. I personally always make this explicit to show what is happening, but c# implicitly makes it the 'int' type (32-bit int).

You can use any name for the enum names and can check if it is a valid enum by using Enum.IsDefined (e.g. to check if 300 is a valid enum name).

update

Okay, actually that's not 100% correct to be honest. This update is just to show what's actually happening under the hood. An enum is a value type with fields that act as names. E.g. the above enum is actually:

public struct Foo 
{ 
    private int _value;
    public static Foo SomeValue { get { return new Foo() { _value = 100 }; } }
}

Notice that the 'int' is the type of the int (in my case explicit). Because it's a value type, it has the same structure as a real integer in memory - which is probably what's being used by the compiler when you're casting.

like image 41
atlaste Avatar answered Nov 03 '22 15:11

atlaste


If you are asking can you store an integer value against an enum then yes you can e.g.

 public enum DurationSeconds
 {
     None = 0,
     FiveMinutesBefore = 300,
     FifteenMinutesBefore = 900,
     ThirtyMinutesBefore = 1800,
     OneHourBefore = 3600,
     TwoHoursBefore = 7200,
     OneDayBefore = 86400,
     TwoDaysBefore = 172800
 }
like image 21
James Avatar answered Nov 03 '22 15:11

James