Что лучшую практику путь состоит в том, чтобы преобразовать перечисление для строкового представления?

У меня есть перечисление как это:

public enum ObectTypes
{
    TypeOne,
    TypeTwo,
    TypeThree,
    ...
    TypeTwenty
 }

затем я должен преобразовать это перечисление для строкового представления. Теперь я делаю этот тот путь:

public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
    string result = string.Empty;
    switch (typeObj)
    {
        case ObjectTypes.TypeOne: result = "This is type T123"; break;
        case ObjectTypes.TypeTwo: result = "Oh man! This is type T234"; break;
        ...
        case ObjectTypes.TypeTwenty: result = "This is type last"; break;
    }

    return result;
}

Я совершенно уверен, что существует лучший путь, действительно делают это, я ищу некоторое хорошее решение для практики.

Править: В строке результата нет никакого шаблона.

Заранее спасибо.

8
задан jaco0646 25 October 2018 в 15:43
поделиться

8 ответов

Я использую атрибут [Description] из System.ComponentModel

Пример:

public enum RoleType
{
    [Description("Allows access to public information")] Guest = 0,
    [Description("Allows access to the blog")] BlogReader = 4,
}

Затем для чтения из это я делаю

public static string ReadDescription<T>(T enumMember)
{
    var type = typeof (T);

    var fi = type.GetField(enumMember.ToString());
    var attributes = (DescriptionAttribute[]) 
            fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
    return attributes.Length > 0 ? 
        attributes[0].Description : 
        enumMember.ToString();
}

Затем используйте

ReadDescription (RoleType.Guest);

Примечание: это решение предполагает приложение с одной культурой, поскольку ничего специально не спрашивалось о нескольких культурах. Если вы находитесь в ситуации, когда вам необходимо обрабатывать несколько культур, я бы использовал DescriptionAttribute или аналогичный для хранения ключа к файлу ресурсов с учетом культуры. Хотя вы можете сохранить член перечисления непосредственно в файле .resx, что создаст максимально возможную связь. Я не вижу причин, по которым вы хотели бы связать внутреннюю работу вашего приложения (имена членов перечисления) с ключевыми значениями, которые существуют для целей интернационализации.

19
ответ дан 5 December 2019 в 04:55
поделиться

Я бы сказал, что это требует рефакторинга.

Замените код типа на класс

0
ответ дан 5 December 2019 в 04:55
поделиться

Я не могу в это поверить... Почему никто не предложил файл Resource?

Сопоставление значений enum со строками в скомпилированном коде хорошо и хорошо как быстрый взлом, но в долгосрочной перспективе это плохая практика и затрудняет рефакторинг кода. Что делать, если добавить (или вычесть) значение из enum? Если вы используете строки из файла ресурсов, все, что вам нужно сделать, это добавить (или удалить) одну запись.

1
ответ дан 5 December 2019 в 04:55
поделиться

Используйте предложенный способ ресурсов:

string GetName(Enum e) {
     return Properties.Resources.ResourcesManager.GetString("_enum_"+e.GetType().ToString().Replace('.','_'));
}

Обработка ошибок - это немного больше ..

4
ответ дан 5 December 2019 в 04:55
поделиться

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

internal static string MapToName(ObjectTypes value) {
  switch (value) { 
    case ObjectTypes.TypeOne: return "T123";
    case ObjectTypes.TypeTwo: return "T234";
    ...
  }
}

public string ConvertToCustomTypeName(ObjectTypes value) {
  return String.Format("This is type {0}", MapToName(value));
}
2
ответ дан 5 December 2019 в 04:55
поделиться

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

Если вас устраивает функция ToString () по умолчанию, просто используйте typeObj.ToString ();

Для словарного подхода вы можете сделать:

private static Dictionary<ObjectTypes, string> enumLookup;

static MyClass()
{
    enumLookup = new Dictionary<ObjectTypes, string>();
    enumLookup.Add(ObjectTypes.TypeOne, "This is type T123");
    enumLookup.Add(ObjectTypes.TypeTwo, "This is type T234");
    // enumLookup.Add...

}

Ваш метод станет:

public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
     // Shouldn't need TryGetValue, unless you're expecting people to mess  with your enum values...
     return enumLookup[typeObj];
}
9
ответ дан 5 December 2019 в 04:55
поделиться

Однажды я использовал настраиваемый атрибут для полей перечисления, который принимал строковый параметр, а затем написал функцию для извлечения строки при задании значения перечисления.

1
ответ дан 5 December 2019 в 04:55
поделиться

Если вы просто хотите использовать имя перечисления (например, TypeOne), вы можете просто вызвать ToString () для самого перечисления

typeObj.ToString()

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

public enum ObectTypes
{
   One,
   Two
}

Dictionary<ObectTypes, String> myDic = new Dictionary<ObectTypes, string>();
myDic.Add( ObectTypes.One, "Something here for One" );
myDic.Add( ObectTypes.Two, "Something here for Two" );
1
ответ дан 5 December 2019 в 04:55
поделиться
Другие вопросы по тегам:

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