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

СУХОЙ (не повторяйся) код

Скажем, если вы хотите изменить значение, font-size: 24px, вы можете сделать n раз, чем один раз в CSS , Плюс размер кода тоже меньше.

Каскадирование / переопределение

Я бы не стал говорить о том, чтобы поместить CSS в отдельный файл, но, безусловно, встроенные стили не одобряются, поскольку встроенные стили нельзя переопределять, кроме как с помощью !important.

Презентация / Разделение контента

Вы действительно должны разделить оба.

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

14 ответов

I like to use properties in a class instead of methods, since they look more enum-like.

Here's a example for a Logger:

public class LogCategory
{
    private LogCategory(string value) { Value = value; }

    public string Value { get; set; }

    public static LogCategory Trace   { get { return new LogCategory("Trace"); } }
    public static LogCategory Debug   { get { return new LogCategory("Debug"); } }
    public static LogCategory Info    { get { return new LogCategory("Info"); } }
    public static LogCategory Warning { get { return new LogCategory("Warning"); } }
    public static LogCategory Error   { get { return new LogCategory("Error"); } }
}

Pass in type-safe string values as a parameter:

public static void Write(string message, LogCategory logCategory)
{
    var log = new LogEntry { Message = message };
    Logger.Write(log, logCategory.Value);
}

Usage:

Logger.Write("This is almost like an enum.", LogCategory.Info);
340
ответ дан 23 November 2019 в 01:32
поделиться

Мой первый вопрос - у Вас есть доступ к самой Базе данных? Это должно быть нормализовано в базе данных, идеально, иначе, любое решение будет подверженным ошибке. По моему опыту, поля данных, полные "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
поделиться

Добавление этого класса

public class DatabasePreference {
    public DatabasePreference([CallerMemberName] string preferenceName = "") {
        PreferenceName = preferenceName;
    }
    public string PreferenceName;
}

Эта работа использует CallerMemberName для уменьшения кодирования

Используя:

//Declare names
public static DatabasePreference ScannerDefaultFlashLight = new DatabasePreference();
public static DatabasePreference ScannerQrCodes = new DatabasePreference();
public static DatabasePreference Scanner1dCodes = new DatabasePreference();

Тест это:

Console.WriteLine(ScannerDefaultFlashLight.PreferenceName);
Console.WriteLine(ScannerDefaultFlashLight.Scanner1dCodes);

вывод:

ScannerDefaultFlashLight
Scanner1dCodes
1
ответ дан 23 November 2019 в 01:32
поделиться

На самом деле вы можете сделать это очень легко. Используйте следующий код.

enum GroupTypes
{
   OEM,
   CMB
};

Затем, если вы хотите получить строковое значение каждого элемента перечисления, просто используйте следующую строку кода.

String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);

Я успешно использовал этот метод в прошлом, и я также использовал Класс констант для хранения строковых констант, оба работают довольно хорошо, но я предпочитаю этот.

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

Вот метод расширения, который я использовал для получения значения перечисления в виде строки. Сначала перечисление.

public enum DatabaseEnvironment
{
    [Description("AzamSharpBlogDevDatabase")]
    Development = 1, 
    [Description("AzamSharpBlogQADatabase")]
    QualityAssurance = 2, 
    [Description("AzamSharpBlogTestDatabase")] 
    Test = 3
}

Атрибут Description взят из System.ComponentModel.

А вот мой метод расширения:

public static string GetValueAsString(this DatabaseEnvironment environment) 
{
    // get the field 
    var field = environment.GetType().GetField(environment.ToString());
    var customAttributes = field.GetCustomAttributes(typeof (DescriptionAttribute), false);

    if(customAttributes.Length > 0)
    {
        return (customAttributes[0] as DescriptionAttribute).Description;  
    }
    else
    {
        return environment.ToString(); 
    }
}

Теперь вы можете получить доступ к перечислению как строковому значению, используя следующий код:

[TestFixture]
public class when_getting_value_of_enum
{
    [Test]
    public void should_get_the_value_as_string()
    {
        Assert.AreEqual("AzamSharpBlogTestDatabase",DatabaseEnvironment.Test.GetValueAsString());  
    }
}
6
ответ дан 23 November 2019 в 01:32
поделиться

Новый в .Net Core 3.0/C# 8.0 (если Ваша рабочая среда позволяет Вам обновлять свой проект) является кратким оператором переключения, который смотрит несколько перечислимый выход. В конце дня это - тот же старый скучный оператор переключения, который мы использовали в течение многих лет.

Только реальная разница здесь - то, что оператор переключения получил новый иск.

public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
    Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
    Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
    Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
    Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
    Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
    Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
    Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
    _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};

Вы заметите, что код, выше которого я скопировал от здесь , на самом деле использует перечисление в качестве параметрического усилителя.

Это не точно, что Вы хотите (и доверяйте мне, я хотел что-то вроде подобного тому, что OP запрашивает в течение долгого времени), но я на самом деле чувствую, что это - своего рода оливковая ветвь от MS. JMO.

Hope это помогает кому-то!

0
ответ дан 23 November 2019 в 01:33
поделиться