文字列値が列挙リストにあるかどうかを確認する方法?


91

私のクエリ文字列には、年齢変数があります ?age=New_Born

この文字列値New_Bornが列挙リストにあるかどうかを確認できる方法はありますか

[Flags]
public enum Age
{
    New_Born = 1,
    Toddler = 2,
    Preschool = 4,
    Kindergarten = 8
}

今のところifステートメントを使用できますが、Enumリストが大きくなる場合。もっと良い方法を見つけたいです。Linqを使用することを考えていますが、その方法がわかりません。


2
Enum.IsDefinedよくない?
leppie

回答:


153

以下を使用できます。

 Enum.IsDefined(typeof(Age), youragevariable)

IsDefinedはEnumインスタンスをチェックする必要があります
Viacheslav Smityukh '29

9
Enum.IsDefined()大文字と小文字が区別されることに注意してください。したがって、これは「ユニバーサルソリューション」ではありません。
チェシャー猫

6
IsDefinedはリフレクションを使用するため、通常はIsDefinedを使用しないことをお勧めします。IsDefinedへの呼び出しは、パフォーマンスとCPUの面で非常に負荷の高い呼び出しになります。代わりにTryParseを使用してください。(pluralsight.comから学んだ)
衛輝市郭

40

Enum.TryParseメソッドを使用できます。

Age age;
if (Enum.TryParse<Age>("New_Born", out age))
{
    // You now have the value in age 
}

5
これは、.NET 4以降でのみ利用可能です
Gary Richter

2
これの問題は、(つまり、「New_Born」文字列の代わりに)任意の整数を指定するとtrueを返すことです。
Romain Vincent

10

成功した場合にtrueを返すTryParseメソッドを使用できます。

Age age;

if(Enum.TryParse<Age>("myString", out age))
{
   //Here you can use age
}

2

IsDefinedは大文字と小文字を区別するため、TryParseを使用する便利な拡張メソッドがあります。

public static bool IsParsable<T>(this string value) where T : struct
{
    return Enum.TryParse<T>(value, true, out _);
}

1

Enum.TryParseを使用して目標を達成する必要があります

これは例です:

[Flags]
private enum TestEnum
{
    Value1 = 1,
    Value2 = 2
}

static void Main(string[] args)
{
    var enumName = "Value1";
    TestEnum enumValue;

    if (!TestEnum.TryParse(enumName, out enumValue))
    {
        throw new Exception("Wrong enum value");
    }

    // enumValue contains parsed value
}

1

私はこれが古いスレッドであることを知っていますが、Enumeratesの属性を使用する少し異なるアプローチと、一致する列挙を見つけるためのヘルパークラスを次に示します。

この方法では、1つの列挙に複数のマッピングを設定できます。

public enum Age
{
    [Metadata("Value", "New_Born")]
    [Metadata("Value", "NewBorn")]
    New_Born = 1,
    [Metadata("Value", "Toddler")]
    Toddler = 2,
    [Metadata("Value", "Preschool")]
    Preschool = 4,
    [Metadata("Value", "Kindergarten")]
    Kindergarten = 8
}

このような私のヘルパークラスで

public static class MetadataHelper
{
    public static string GetFirstValueFromMetaDataAttribute<T>(this T value, string metaDataDescription)
    {
        return GetValueFromMetaDataAttribute(value, metaDataDescription).FirstOrDefault();
    }

    private static IEnumerable<string> GetValueFromMetaDataAttribute<T>(T value, string metaDataDescription)
    {
        var attribs =
            value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof (MetadataAttribute), true);
        return attribs.Any()
            ? (from p in (MetadataAttribute[]) attribs
                where p.Description.ToLower() == metaDataDescription.ToLower()
                select p.MetaData).ToList()
            : new List<string>();
    }

    public static List<T> GetEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).Any(
                        p => p.ToLower() == value.ToLower())).ToList();
    }

    public static List<T> GetNotEnumeratesByMetaData<T>(string metadataDescription, string value)
    {
        return
            typeof (T).GetEnumValues().Cast<T>().Where(
                enumerate =>
                    GetValueFromMetaDataAttribute(enumerate, metadataDescription).All(
                        p => p.ToLower() != value.ToLower())).ToList();
    }

}

その後、次のようなことができます

var enumerates = MetadataHelper.GetEnumeratesByMetaData<Age>("Value", "New_Born");

そして完全を期すためにここに属性があります:

 [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public class MetadataAttribute : Attribute
{
    public MetadataAttribute(string description, string metaData = "")
    {
        Description = description;
        MetaData = metaData;
    }

    public string Description { get; set; }
    public string MetaData { get; set; }
}

0

年齢を解析するには:

Age age;
if (Enum.TryParse(typeof(Age), "New_Born", out age))
  MessageBox.Show("Defined");  // Defined for "New_Born, 1, 4 , 8, 12"

定義されているかどうかを確認するには:

if (Enum.IsDefined(typeof(Age), "New_Born"))
   MessageBox.Show("Defined");

Age列挙型の使用方法によっては、フラグが適切でない場合があります。おそらくご存知のとおり[Flags]、ビットマスクのように複数の値を許可することを示します。 複数の値があるため、はIsDefinedfalseを返しAge.Toddler | Age.Preschoolます。


2
検証されていない入力なので、TryParseを使用する必要があります。
サービー

1
MessageBoxは、Web環境では実際には意味がありません。
サービー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.