как проверить, если строковое значение находится в Перечислимом списке?
в моей строке запроса у меня есть переменная возраста ?age=New_Born
.
есть ли способ проверить, если это строковое значение New_Born
находится в моем списке перечислений
[Flags]
public enum Age
{
New_Born = 1,
Toddler = 2,
Preschool = 4,
Kindergarten = 8
}
я мог бы использовать оператор if прямо сейчас, но если мой список перечислений станет больше. Я хочу найти лучший способ сделать это. Я думаю о том, чтобы использовать Linq, просто не знаю, как это сделать.
7 ответов:
вы можете использовать enum.Метод TryParse:
Age age; if (Enum.TryParse<Age>("New_Born", out age)) { // You now have the value in age }
можно использовать TryParse метод, который возвращает true, если его успешным:
Age age; if(Enum.TryParse<Age>("myString", out age)) { //Here you can use age }
Я знаю, что это старый поток, но вот немного другой подход, используя атрибуты на перечислениях, а затем вспомогательный класс, чтобы найти перечисление, которое соответствует.
таким образом, вы можете иметь несколько сопоставлений на одном перечислении.
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; } }
У меня есть удобный метод расширения, который использует TryParse, поскольку IsDefined чувствителен к регистру.
public static bool IsParsable<T>(this string value) where T : struct { return Enum.TryParse<T>(value, true, out _); }
вы должны использовать перечислимый.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 }
чтобы разобрать возраст:
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]
указывает, что вы хотите разрешить несколько значений (как в битовой маской).IsDefined
вернет false дляAge.Toddler | Age.Preschool
потому что он имеет несколько значений.