6

C# では、Enum を理解するのに少し困惑しています。

私の特定のケースでは、次のような名前値形式で定数値を保存する必要があります>

300 秒 = 5 分

現時点では、このクラスを使用しています。

  • 代わりに Enum を使用できるので、Enum クラスは次のようになりますか?
  • 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;
        }

    }
}
4

5 に答える 5

8

辞書キーとして使用でき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 ];
于 2013-01-21T09:08:14.397 に答える
5

列挙型を説明属性で装飾し、後でリフレクションを通じてアクセスできます。例えば、

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

于 2013-01-21T09:10:01.043 に答える
3

列挙型は、実際には名前付き整数型です。例えば

public enum Foo : int 
{
   SomeValue = 100,
}

これは、「int」型と値を持つ Foo 列挙を作成することを意味します。私は個人的に何が起こっているかを示すために常にこれを明示的にしていますが、c# は暗黙的にそれを「int」型 (32 ビット int) にしています。

列挙名には任意の名前を使用でき、Enum.IsDefined を使用して有効な列挙であるかどうかを確認できます (たとえば、300 が有効な列挙名であるかどうかを確認する場合)。

アップデート

正直なところ、それは 100% 正しいわけではありません。このアップデートは、ボンネットの下で実際に何が起こっているかを示すためのものです。列挙型は、名前として機能するフィールドを持つ値型です。たとえば、上記の列挙型は実際には次のとおりです。

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

「int」はintの型であることに注意してください(私の場合は明示的です)。これは値型であるため、メモリ内の実際の整数と同じ構造を持ちます。これはおそらく、キャスト時にコンパイラによって使用されるものです。

于 2013-01-21T09:13:12.743 に答える
2

列挙型に対して整数値を保存できるかどうか尋ねている場合は、はい、たとえばできます

 public enum DurationSeconds
 {
     None = 0,
     FiveMinutesBefore = 300,
     FifteenMinutesBefore = 900,
     ThirtyMinutesBefore = 1800,
     OneHourBefore = 3600,
     TwoHoursBefore = 7200,
     OneDayBefore = 86400,
     TwoDaysBefore = 172800
 }
于 2013-01-21T09:08:29.807 に答える
0

私が通常行うこととは逆に、別の回答を追加します。これは、問題に対する IMO の回答です。

通常、実行時チェックを実際に使用する前に、できる限り多くのチェックをコンパイラーに実行してもらいます。つまり、この場合、値を取得するために 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]; } }

}

このようなプログラムを作成する場合、言語はいくつかの点で役立ちます。

  • 定義されていない期間は使用できません
  • 正確には、辞書を一度だけ初期化します。型が構築されたとき
  • Enum.IsDefined は、間違った int 値を使用しないようにします (たとえば、new Reminders((TimeSpanEnum)5) は失敗します)。
于 2013-01-21T09:41:38.117 に答える