是否可以像字典一样使用枚举和对值?
本文关键字:枚举 一样 字典 是否 | 更新日期: 2023-09-27 17:54:57
在c#中我对Enum的理解有点困惑。
在我的特殊情况下,我需要以Name - value格式存储常量值,如>
300秒= 5分钟
目前我正在使用这个类。
- 将有可能使用Enum代替,所以我枚举类看起来像吗?
- 我可以在枚举中存储一对值吗?
你能给我一个代码样本吗?
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;
}
}
}
您可以使用Tuple<int, int>
作为字典键(至少对于。net>= 4)。
但是由于您实际上想要存储TimeSpan
,因此使用它作为键。
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");
}
你可以这样得到翻译:
var quarter = TimeSpan.FromMinutes(15);
string text = TimeSpanText[ quarter ];
您可以用描述属性装饰您的枚举,并在稍后通过反射访问它们。例如,
enum ReminderTimes
{
[Description("None")]
None = 0,
[Description("5 minutes before")]
FiveMinutesBefore = 300,
[Description("15 minutes before")]
FifteenMinutesBefore = 900
}
您可以通过以下方式获得描述:
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;
}
参见:http://www.codeproject.com/Articles/13821/Adding-Descriptions-to-your-Enumerations
enum实际上是一种命名的整数类型。例如
public enum Foo : int
{
SomeValue = 100,
}
,这意味着你创建了一个Foo枚举类型为'int'和一些值。我个人总是显式地显示正在发生的事情,但是c#隐式地使它成为'int'类型(32位int)。
可以使用任何名称作为枚举名称,并且可以使用enum检查它是否是一个有效的枚举。IsDefined(例如检查300是否是一个有效的enum名称)。
好吧,说实话,这并不是100%正确的。这个更新只是为了展示幕后实际发生的事情。枚举是一种值类型,其字段充当名称。例如,上面的枚举实际上是:
public struct Foo
{
private int _value;
public static Foo SomeValue { get { return new Foo() { _value = 100 }; } }
}
注意,'int'是int的类型(在我的例子中是显式的)。因为它是一个值类型,所以它在内存中具有与实际整数相同的结构-这可能是当您进行类型转换时编译器所使用的。
如果你问你是否可以在enum中存储整数值,那么是的,你可以,例如
public enum DurationSeconds
{
None = 0,
FiveMinutesBefore = 300,
FifteenMinutesBefore = 900,
ThirtyMinutesBefore = 1800,
OneHourBefore = 3600,
TwoHoursBefore = 7200,
OneDayBefore = 86400,
TwoDaysBefore = 172800
}
与我通常所做的相反,我将添加另一个答案,我认为这是问题的答案。
您通常希望编译器在实际使用运行时检查之前做尽可能多的检查。这意味着在本例中使用Enum来获取值:
// provides a strong type when using values in memory to make sure you don't enter incorrect values
public enum TimeSpanEnum : int
{
Minutes30 = 30,
Minutes60 = 60,
}
public class Reminders
{
static Reminders()
{
names.Add(TimeSpanEnum.Minutes30, "30 minutes");
names.Add(TimeSpanEnum.Minutes60, "60 minutes");
}
public Reminders(TimeSpanEnum ts)
{
if (!Enum.IsDefined(typeof(TimeSpanEnum), ts))
{
throw new Exception("Incorrect value given for time difference");
}
}
private TimeSpanEnum value;
private static Dictionary<TimeSpanEnum, string> names = new Dictionary<TimeSpanEnum, string>();
public TimeSpan Difference { get { return TimeSpan.FromSeconds((int)value); } }
public string Name { get { return names[value]; } }
}
当创建这样的程序时,语言在以下几个方面帮助您:
- 不能使用未定义的时间跨度
- 它只初始化字典一次,确切地说:当构造类型时
- 枚举。IsDefined确保你不会使用不正确的int值(例如:new Reminders((TimeSpanEnum)5)将失败。