Можно ли определить неявное преобразование перечислений в c #?
что-то, что могло бы этого достичь?
public enum MyEnum
{
one = 1, two = 2
}
MyEnum number = MyEnum.one;
long i = number;
Если нет, то почему?
c#
enums
implicit-conversion
implicit
Адам Нейлор
источник
источник
enum YesNo {Yes, No}
которое можно неявно преобразовать в bool.Ответы:
Выход есть. Учтите следующее:
Вышеупомянутое предлагает неявное преобразование:
Это немного больше работы, чем объявление обычного перечисления (хотя вы можете реорганизовать некоторые из вышеперечисленных в общий общий базовый класс). Вы можете пойти еще дальше, реализовав в базовом классе IComparable и IEquatable, а также добавив методы для возврата значения DescriptionAttributes, объявленных имен и т. Д. И т. Д.
Я написал базовый класс (RichEnum <>) для обработки большей части основной работы, что упрощает приведенное выше объявление перечислений до:
Базовый класс (RichEnum) указан ниже.
источник
Вы не можете выполнять неявные преобразования (кроме нуля), и вы не можете писать свои собственные методы экземпляра - однако вы, вероятно, можете написать свои собственные методы расширения:
Однако это мало что дает (по сравнению с простым явным приведением).
Один из основных случаев, когда я видел, что люди хотят этого, - это
[Flags]
манипуляции с помощью дженериков, то естьbool IsFlagSet<T>(T value, T flag);
метода. К сожалению, C # 3.0 не поддерживает операторы в универсальных шаблонах, но вы можете обойти это, используя подобные вещи , которые делают операторы полностью доступными для универсальных шаблонов.источник
источник
static class
Я полагаю, вы могли бы использовать . В окончательномIL
коде нет аргументов в пользу того или иного случая .Я адаптировал отличный базовый класс RichEnum Марка.
Крепежная
Престижность Марку за великолепную идею + реализацию, и всем вам:
Пример использования, который я запускал в моно:
Производство продукции
Примечание: для mono 2.6.7 требуется дополнительное явное приведение, которое не требуется при использовании mono 2.8.2 ...
источник
FirstOrDefault
, чтобы не предполагать, что есть только один атрибут). Является ли предположение о таких вещах «хорошей идеей» (или плохой , если на то пошло), конечно, зависит от контекстаTDerived instance = (TDerived)field.GetValue(null);
приводит к тому,instance
чтоnull
. Похоже, что среда выполнения Mono должна иметь другой порядок инициализации типов, чем .NET, что позволяет этому работать. Непонятные! Вместо этого мне пришлось переместить этот код в статический метод и вызвать его из инициализатора типа в подклассе.Вы не можете объявлять неявные преобразования для перечисляемых типов, потому что они не могут определять методы. Ключевое слово implicit C # компилируется в метод, начинающийся с op_, и в этом случае он не будет работать.
источник
Возможно, вы могли бы, но не для перечисления (вы не можете добавить к нему метод). Вы можете добавить неявное преобразование в свой собственный класс, чтобы разрешить преобразование в него перечисления,
Возникает вопрос: почему?
В целом .Net избегает (и вам следует тоже) любого неявного преобразования, при котором данные могут быть потеряны.
источник
Если вы определяете базу перечисления как длинную, вы можете выполнить явное преобразование. Я не знаю, можете ли вы использовать неявные преобразования, поскольку в перечислениях не могут быть определены методы.
Кроме того, имейте в виду, что неитализированное перечисление по умолчанию будет иметь значение 0 или первый элемент, поэтому в ситуации выше, вероятно, также будет лучше определить
zero = 0
.источник
: long
; явное преобразование нормально работало бы и без него. Единственное допустимое неявное преобразование - ноль.перечисления в значительной степени бесполезны для меня из-за этого OP.
В итоге я все время занимаюсь фотографиями:
простое решение
Классическим примером проблемы является набор VirtualKey для обнаружения нажатий клавиш.
проблема здесь в том, что вы не можете проиндексировать массив с помощью enum, потому что он не может неявно преобразовать enum в ushort (хотя мы даже основали перечисление на ushort)
в этом конкретном контексте перечисления устарели в следующей структуре данных. , , ,
источник
Я работал над проблемой с ответом sehe при запуске кода в MS .net (не Mono). Для меня проблема возникла в .net 4.5.1, но, похоже, затронули и другие версии.
Проблема
Доступ к
public static TDervied MyEnumValue
отражению (черезFieldInfo.GetValue(null)
это не Initialize упомянутого поля.Обходной путь
Вместо присвоения имен
TDerived
экземплярам при статическом инициализатореRichEnum<TValue, TDerived>
это выполняется лениво при первом обращении кTDerived.Name
. Код:который - в моем случае - основан на
EquatableBase<T>
:Заметка
Приведенный выше код не включает все функции исходного ответа Марка !
Спасибо
Спасибо Марку за его
RichEnum
реализацию и спасибо sehe за некоторые улучшения!источник
Я нашел еще более простое решение, взятое отсюда /codereview/7566/enum-vs-int-wrapper-struct. Я вставил приведенный ниже код из этой ссылки на случай, если он не будет работать в будущем.
источник
Я создал эту утилиту, чтобы помочь мне преобразовать Enum в PrimitiveEnum и PrimitiveEnum в
byte, sbyte, short, ushort, int, uint, long, or ulong
.Таким образом, это технически преобразует любое перечисление в любое его примитивное значение.
См. Фиксацию на https://github.com/McKabue/McKabue.Extentions.Utility/blob/master/src/McKabue.Extentions.Utility/Enums/PrimitiveEnum.cs
источник
uint
s, для которых сама игра обычно делаетenum
s, но фреймворк ничего о нем не знает. Необходимость(uint)
при вызове рамки была боль. Ваша идея задом наперед работает отлично. Вместо того, чтобыstruct
хранитьEnum
, у меня есть,struct IdNumber
который хранит,uint
но неявно преобразуетEnum
s, которые использует игра. Вместо того, чтобы вводить параметры фреймворка какuint
, я могу ввести ихIdNumber
, и фреймворк может эффективно передавать их внутри, даже выполняя с ними комплексные операции.Введение неявных преобразований для перечисляемых типов нарушит безопасность типов, поэтому я бы не рекомендовал этого делать. Почему вы хотите это сделать? Единственный вариант использования этого, который я видел, - это когда вы хотите поместить значения перечисления в структуру с заранее определенным макетом. Но даже в этом случае вы можете использовать тип enum в структуре и просто сказать Маршаллеру, что он должен с этим делать.
источник