Соединение перечислений со строками в C#

Я знаю, что следующее не возможно, потому что тип Перечисления должен быть интервалом

enum GroupTypes
{
    TheGroup = "OEM",
    TheOtherGroup = "CMB"
}

От моей базы данных я получаю поле с кодами incomprehensive ( OEM и CMBs). Я хотел бы сделать это поле в enum или что-то еще понятное. Поскольку, если цель является удобочитаемостью, решение должно быть кратким.

Что другие опции я имею?

296
задан Chad 18 September 2019 в 17:15
поделиться

0 ответов

Мой первый вопрос - у Вас есть доступ к самой Базе данных? Это должно быть нормализовано в базе данных, идеально, иначе, любое решение будет подверженным ошибке. По моему опыту, поля данных, полные "OEM" и "CMB", имеют тенденцию завершать вещи наличия как "oem" и другие 'загаженные данные', смешанные в со временем.... Если можно нормализовать его, Вы могли бы использовать ключ в таблице, содержащей элементы как Ваше Перечисление, и Вы сделаны с намного более чистой структурой.

, Если бы это не доступно, я сделал бы Ваше Перечисление и сделал бы класс для парсинга строки в Перечисление для Вас. Это, по крайней мере, дало бы Вам некоторую гибкость в обработке нестандартных записей и намного большей гибкости для захвата или ошибок из-за неправильного обращения, чем выполнение любого из обходных решений с помощью Перечисления. Синтаксический анализ/Отражение/и т.д. Словарь работал бы, но мог сломаться, если бы у Вас когда-нибудь есть проблемы случая, и т.д.

я рекомендовал бы писать класс, таким образом, можно сделать:

// I renamed this to GroupType, since it sounds like each element has a single type...
GroupType theType = GroupTypeParser.GetGroupType(theDBString);

Это сохраняет большую часть Вашей удобочитаемости, не имея необходимость изменять DB.

2
ответ дан Reed Copsey 23 November 2019 в 01:32
поделиться

Я просто создал бы словарь и использовал бы код как ключ.

Редактирование: Для обращения к комментарию о выполнении обратного поиска (находящий ключ) это не было бы ужасно эффективно. Если бы это необходимо, я записал бы новый класс для обработки его.

2
ответ дан jhale 23 November 2019 в 01:32
поделиться

Я превратил бы его в класс избегание перечисления в целом. И затем с использованием typehandler Вы могли создать объект при захвате его от дб.

IE:

public class Group
{
    public string Value{ get; set; }
    public Group( string value ){ Value = value; } 
    public static Group TheGroup() { return new Group("OEM"); }
    public static Group OtherGroup() { return new Group("CMB"); }

}
2
ответ дан Bryan Rowe 23 November 2019 в 01:32
поделиться

Вы рассмотрели таблицу поиска с помощью Словаря?

enum GroupTypes
{
    TheGroup,
    TheOtherGroup
}

Dictionary<string, GroupTypes> GroupTypeLookup = new Dictionary<string, GroupTypes>();
// initialize lookup table:
GroupTypeLookup.Add("OEM", TheGroup);
GroupTypeLookup.Add("CMB", TheOtherGroup);

можно тогда использовать GroupTypeLookup. TryGetValue () для поиска строки, когда Вы читаете его.

4
ответ дан Jim Mischel 23 November 2019 в 01:32
поделиться

Попытайтесь добавить константы к статическому классу. Вы не заканчиваете с Типом, но у Вас будут читаемые, организованные константы:

public static class GroupTypes {

    public const string TheGroup = "OEM";
    public const string TheOtherGroup = "CMB";

}
16
ответ дан Chad 23 November 2019 в 01:32
поделиться

Используйте класс.

Редактирование: Лучший пример

class StarshipType
{
    private string _Name;
    private static List<StarshipType> _StarshipTypes = new List<StarshipType>();

    public static readonly StarshipType Ultralight = new StarshipType("Ultralight");
    public static readonly StarshipType Light = new StarshipType("Light");
    public static readonly StarshipType Mediumweight = new StarshipType("Mediumweight");
    public static readonly StarshipType Heavy = new StarshipType("Heavy");
    public static readonly StarshipType Superheavy = new StarshipType("Superheavy");

    public string Name
    {
        get { return _Name; }
        private set { _Name = value; }
    }

    public static IList<StarshipType> StarshipTypes
    {
        get { return _StarshipTypes; }
    }

    private StarshipType(string name, int systemRatio)
    {
        Name = name;
        _StarshipTypes.Add(this);
    }

    public static StarshipType Parse(string toParse)
    {
        foreach (StarshipType s in StarshipTypes)
        {
            if (toParse == s.Name)
                return s;
        }
        throw new FormatException("Could not parse string.");
    }
}
13
ответ дан Kevin Doyon 23 November 2019 в 01:32
поделиться

Создайте второе перечисление для Вашего DB, содержащего следующее:

enum DBGroupTypes
{
    OEM = 0,
    CMB = 1
}

Теперь, можно использовать Перечисление. Синтаксический анализ для получения корректного значения DBGroupTypes от строк "OEM" и "CMB". Можно тогда преобразовать тех, которых к интервалу и получить правильные значения от правильного перечисления Вы хотите использовать далее в Вашей модели.

13
ответ дан abatishchev 23 November 2019 в 01:32
поделиться

Можно добавить атрибуты к объектам в перечислении и затем использовать отражение для получения значений от атрибутов.

необходимо было бы использовать "полевой" спецификатор для применения атрибутов, как так:

enum GroupTypes
{
    [field:Description("OEM")]
    TheGroup,

    [field:Description("CMB")]
    TheOtherGroup
}

Вы тогда размышляли бы над статическими полями типа перечисления (в этом случае GroupTypes) и добрались бы DescriptionAttribute для значения, Вы искали использование отражения:

public static DescriptionAttribute GetEnumDescriptionAttribute<T>(
    this T value) where T : struct
{
    // The type of the enum, it will be reused.
    Type type = typeof(T);

    // If T is not an enum, get out.
    if (!type.IsEnum) 
        throw new InvalidOperationException(
            "The type parameter T must be an enum type.");

    // If the value isn't defined throw an exception.
    if (!Enum.IsDefined(type, value))
        throw new InvalidEnumArgumentException(
            "value", Convert.ToInt32(value), type);

    // Get the static field for the value.
    FieldInfo fi = type.GetField(value.ToString(), 
        BindingFlags.Static | BindingFlags.Public);

    // Get the description attribute, if there is one.
    return fi.GetCustomAttributes(typeof(DescriptionAttribute), true).
        Cast<DescriptionAttribute>().SingleOrDefault();
}

я решил возвратиться DescriptionAttribute самостоятельно выше, если Вы хотите быть в состоянии определить, применяется ли атрибут даже.

28
ответ дан casperOne 23 November 2019 в 01:32
поделиться

Вы могли также использовать дополнительную модель:

public enum MyEnum
{
    [Description("String 1")]
    V1= 1,
    [Description("String 2")]
    V2= 2
} 

Ваше Дополнительное использование Класса

public static class MyEnumExtensions
{
    public static string ToDescriptionString(this MyEnum val)
    {
        DescriptionAttribute[] attributes = (DescriptionAttribute[])val
           .GetType()
           .GetField(val.ToString())
           .GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : string.Empty;
    }
} 

:

MyEnum myLocal = MyEnum.V1;
print(myLocal.ToDescriptionString());
152
ответ дан kmote 23 November 2019 в 01:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: