Как к TryParse для Перечисления значений?

Для диаграмм последовательности, только, попытка websequencediagrams.com . Это - свободно распространяемое (свободный для основных задач, оплаченных расширенные функции) продукт, и позволяет Вам быстро строчить схему ни с кем беспокоящимся со строками и шаблонами.

Alice->Bob: Authentication Request
note left of Bob: Bob thinks about it
Bob->Alice: Authentication Response

91
задан Pierre Arnaud 13 September 2011 в 14:24
поделиться

11 ответов

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

Если вы используете перечисления битовых полей (то есть флаги), вы также должны обрабатывать строку вроде «MyEnum.Val1 | MyEnum.Val2» который представляет собой комбинацию двух значений перечисления. Если вы просто вызовете Enum.IsDefined с этой строкой, он вернет false, даже если Enum. Parse обрабатывает это правильно.

Update

Как упоминалось Лизой и Кристианом в комментариях, Enum.TryParse теперь доступен для C # в .NET4 и выше.

Документы MSDN

31
ответ дан 24 November 2019 в 06:46
поделиться

Enum.IsDefined сделает все. Возможно, он не так эффективен, как TryParse, но он будет работать без обработки исключений.

public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
    if (!Enum.IsDefined(typeof(TEnum), strEnumValue))
        return defaultValue;

    return (TEnum)Enum.Parse(typeof(TEnum), strEnumValue);
}

Стоит отметить: в .NET 4.0 был добавлен метод TryParse .

101
ответ дан 24 November 2019 в 06:46
поделиться

В конце концов вы должны реализовать это вокруг Enum.GetNames :

public bool TryParseEnum<T>(string str, bool caseSensitive, out T value) where T : struct {
    // Can't make this a type constraint...
    if (!typeof(T).IsEnum) {
        throw new ArgumentException("Type parameter must be an enum");
    }
    var names = Enum.GetNames(typeof(T));
    value = (Enum.GetValues(typeof(T)) as T[])[0];  // For want of a better default
    foreach (var name in names) {
        if (String.Equals(name, str, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) {
            value = (T)Enum.Parse(typeof(T), name);
            return true;
        }
    }
    return false;
}

Дополнительные примечания:

  • Enum.TryParse включен в .NET 4 . См. Здесь http://msdn.microsoft.com/library/dd991876 (VS.100) .aspx
  • Другой подход состоит в том, чтобы напрямую обернуть Enum.Parse , перехватывая исключение, возникающее, когда это не удается. Это может быть быстрее при обнаружении совпадения, но, скорее всего, будет медленнее, если нет. В зависимости от данных, которые вы обрабатываете, это может быть или не быть чистым улучшением.

РЕДАКТИРОВАТЬ: Только что видел лучшую реализацию, которая кэширует необходимую информацию: http://damieng.com/blog/2010 / 10/17 / перечисления-лучше-синтаксис-улучшенная-производительность-и-tryparse-in-net-3-5

16
ответ дан 24 November 2019 в 06:46
поделиться

Единственный способ избежать обработки исключений - использовать метод GetNames (), и все мы знаем, что исключениями не следует злоупотреблять для общей логики приложения :)

1
ответ дан 24 November 2019 в 06:46
поделиться

В настоящее время нет стандартного Enum.TryParse. Это было запрошено в Connect ( Все еще нет Enum.TryParse ), и был получен ответ, указывающий на возможное включение в следующую структуру после .NET 3.5. На данный момент вам придется реализовать предлагаемые обходные пути.

2
ответ дан 24 November 2019 в 06:46
поделиться

Допустимо ли кэширование динамически сгенерированной функции / словаря?

Потому что вам (кажется) неизвестен тип Из перечисления заранее, первое выполнение могло бы сгенерировать то, чем могли бы воспользоваться последующие исполнения.

Вы даже можете кэшировать результат Enum.GetNames ()

Вы пытаетесь оптимизировать для ЦП или памяти? Вам действительно это нужно?

1
ответ дан 24 November 2019 в 06:46
поделиться

Взгляните на сам класс Enum (структура?). Для этого есть метод Parse, но я не уверен насчет трипарса.

-1
ответ дан 24 November 2019 в 06:46
поделиться

Это плохая идея, если вы хотите, чтобы ваши изображения и информация о стилях кэшировались отдельно. Кроме того, если вы кодируете большое изображение или значительное количество изображений в свой файл css, браузеру потребуется больше времени, чтобы загрузить файл, оставив ваш сайт без какой-либо информации о стиле, пока загрузка не завершится. Для небольших изображений, которые вы не собираетесь часто менять, если когда-либо, это прекрасное решение.

что касается генерации кодировки base64:

0
ответ дан 24 November 2019 в 06:46
поделиться

У меня есть оптимизированная реализация, которую вы можете использовать в UnconstrainedMelody . Фактически он просто кэширует список имен, но делает это красивым, строго типизированным, обобщенно ограниченным способом :)

4
ответ дан 24 November 2019 в 06:46
поделиться

Этот метод преобразует тип перечисления:

  public static TEnum ToEnum<TEnum>(object EnumValue, TEnum defaultValue)
    {
        if (!Enum.IsDefined(typeof(TEnum), EnumValue))
        {
            Type enumType = Enum.GetUnderlyingType(typeof(TEnum));
            if ( EnumValue.GetType() == enumType )
            {
                string name = Enum.GetName(typeof(HLink.ViewModels.ClaimHeaderViewModel.ClaimStatus), EnumValue);
                if( name != null)
                    return (TEnum)Enum.Parse(typeof(TEnum), name);
                return defaultValue;
            }
        }
        return (TEnum)Enum.Parse(typeof(TEnum), EnumValue.ToString());
    } 

Он проверяет базовый тип и сравнивает имя с ним для анализа. Если ничего не получится, он вернет значение по умолчанию.

-2
ответ дан 24 November 2019 в 06:46
поделиться

TryParse не существует, потому что тип Enum неизвестен до времени выполнения. TryParse, который следует той же методологии, что и метод Date.TryParse, вызовет неявную ошибку преобразования для параметра ByRef.

Я предлагаю сделать что-то вроде этого:

//1 line call to get value
MyEnums enumValue = (Sections)EnumValue(typeof(Sections), myEnumTextValue, MyEnums.SomeEnumDefault);

//Put this somewhere where you can reuse
public static object EnumValue(System.Type enumType, string value, object NotDefinedReplacement)
{
    if (Enum.IsDefined(enumType, value)) {
        return Enum.Parse(enumType, value);
    } else {
        return Enum.Parse(enumType, NotDefinedReplacement);
    }
}
0
ответ дан 24 November 2019 в 06:46
поделиться
Другие вопросы по тегам:

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