C # enum.ToString () бокс: разрешить или подавить? - PullRequest
1 голос
/ 27 июня 2019

Итак, недавно мы установили расширение 'Clr Heap Allocation Analyzer' для Visual Studio, чтобы проверить наш код на наличие проблем с выделением кучи, вызванных упаковкой, среди прочего.Мы столкнулись с предупреждением «HAA0102», которое дает следующее описание:

Не переопределенный вызов виртуального метода для типа значения добавляет бокс или ограниченную инструкцию

Это относится к проверке условий в следующей строке кода:

if(instanceType == Enums.Tags.DialoguePanel.ToString())
{
     // Some code handling
}
else if(instanceType == Enums.Tags.InfoPanel.ToString())
{
    // Some other code handling
}

Для контекста Enums.Tags.DialoguePanel ссылается на следующее объявление enum:

public enum Tags
        {
            InfoPanel,
            DialoguePanel,
            WarningPanel
        }

Теперь я понимаючто enum является типом значения и, следовательно, Enums.Tags.DialoguePanel является типом значения.Я также понимаю, что к .ToString() относится, в основном, к ссылочному типу (строке).

Мой вопрос заключается в том, нужно ли проводить рефакторинг таких линий, чтобы избежать упаковки (и если да, то как?) Или лучше подавить это предупреждение для этих конкретных случаев?Пожалуйста, имейте в виду, что нам нужно сохранить типы перечислений.Они используются в качестве контролируемого способа предоставления пользовательских опций (в раскрывающемся списке).Рефакторинг тех, которые относятся к другому типу, потребует МНОГО работы (что хорошо, если производительность будет значительно увеличена).

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

Ответы [ 2 ]

3 голосов
/ 27 июня 2019

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

Форсирование строкового значения, конечно, может пойти не так, так что это следует считать «этапом проверки».Однако после того, как значение enum будет действительным, вы не столкнетесь с проблемами такого рода, которые, помимо того, что они немного снижают производительность, по моему скромному мнению, также подвержены ошибкам (что произойдет, если вы ожидаете, что значение соответствует одному изперечислимые значения и никто не делает ?).

// "Validation"
instanceType = (Enums.Tags) Enum.Parse(typeof(Enums.Tags), value)

// Usage
if(instanceType == Enums.Tags.DialoguePanel)
{
     // Some code handling
}
else if(instanceType == Enums.Tags.InfoPanel)
{
    // Some other code handling
}
0 голосов
/ 27 июня 2019

Теперь я понимаю, что enum является типом значения и, следовательно, Enums.Tags.DialoguePanel является типом значения.Я также понимаю, что к .ToString() относится, в основном, к типу ссылки (строка).

Это не совсем так.Это связано с тем, что Enum.ToString вызывает метод Enum.GetValue, который возвращает базовое значение в виде object - отсюда и операция упаковки.string является ссылочным типом, поэтому он не в штучной упаковке.И только из-за преобразования строк бокс не понадобится.

И да, мы получаем строки с веб-сервера.Хотя мы можем попытаться разобрать строку в значение enum, снижение производительности нежелательно, очевидно.

Я действительно однажды создал универсальный Enum<TEnum> класс для enumоперации без бокса.И хотя блокировка Enum<TEnum>.ToString примерно в 20 раз быстрее (по крайней мере, в этом тесте .NET Fiddle ), я думаю, что потеря производительности, вызванная боксом, по сравнению с временем отклика веб-сервера незначительна, поэтомуВы можете просто подавить предупреждение.Но не стесняйтесь , попробуйте , если хотите.

...