web-dev-qa-db-ja.com

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

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

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

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

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

80
qinking126

次を使用できます。

 Enum.IsDefined(typeof(Age), youragevariable)
135
AaronS

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

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

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

Age age;

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

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

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

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; }
}
1
jwsadler

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

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

年齢を解析するには:

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 enumの使用方法によっては、flagsが正しくない場合があります。おそらくご存じのとおり、[Flags]は、(ビットマスクのように)複数の値を許可することを示します。 IsDefinedは、複数の値があるため、Age.Toddler | Age.Preschoolに対してfalseを返します。

0
agent-j

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
}
0