Являются ли .net Enums преобразовываемыми типами? (маршаллинг)

По-видимому, есть список непреобразуемых типов, и пока я не вижу в нем конкретно Enums. Они вообще мутные? Или это зависит от того, объявлены ли они с непреобразуемым базовым типом?

//e.g.
internal enum SERVERCALL : uint
{
    IsHandled = 0,
    Rejected = 1,
    RetryLater = 2,
}

Ссылки исчерпаны:


person Tim Lovell-Smith    schedule 07.04.2011    source источник


Ответы (4)


Перечисления являются непреобразуемыми типами. Из enum документации по ключевым словам:

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

Поскольку базовый тип является целочисленным (все они входят в список непреобразуемых типов), перечисление также является преобразуемым.

person Bradley Grainger    schedule 07.04.2011

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

person Aliostad    schedule 07.04.2011
comment
Это должен быть ответ. - person Rick the Scapegoat; 09.08.2017
comment
Контрпредложение Nitpick: типы enum являются непреобразуемыми, КОГДА его значения имеют такое же представление в управляемой памяти, как и в неуправляемой памяти, что ВСЕГДА, ПРЕДПОЛАГАЯ, что вы правильно определили базовый тип перечисления, чтобы он соответствовал размеру неуправляемого типа, и фактические значения перечисление также соответствует перечислению, определенному для неуправляемого кода. - person Tim Lovell-Smith; 08.01.2019
comment
Какая разница между типами, которые могут быть преобразованы, и значениями, которые в любом случае могут быть преобразованы? Я бы предположил, что мы должны сказать, что тип преобразовывается только, если его размер одинаков, и все его значения преобразовываются. т.е. интерпретация определенных значений в памяти управляемым кодом и неуправляемым кодом должна быть одинаковой. - person Tim Lovell-Smith; 07.07.2020

Алиостад правильный. Например, если кто-то пытается выполнить оператор:

int size = Marshal.SizeOf( System.ConsoleColor.Red );

затем выдается исключение ArgumentException с сообщением:

Тип System.ConsoleColor нельзя маршалировать как неуправляемую структуру; невозможно вычислить осмысленный размер или смещение.

Однако заявление:

int size = Marshal.SizeOf( (int)System.ConsoleColor.Red );

работает просто отлично, как и следовало ожидать.

Аналогично заявление:

int enumSize = Marshal.SizeOf( typeof(ConsoleColor) );

терпит неудачу, но утверждение:

int enumSize = Marshal.SizeOf( Enum.GetUnderlyingType( typeof(ConsoleColor) ) );

удается.

К сожалению, документация Microsoft для Marshal.SizeOf( object ) дефицитен; эта страница даже не включает ArgumentException в список возможных исключений. Документ для Marshal.SizeOf( Type ) перечисляет ArgumentException, но говорит только, что он вызывается, когда тип является универсальным (что верно, но не распространяется на приведенный выше пример).

(Также документация для enum ключевое слово Enum и Типы перечисления в Руководстве по программированию на C# делают < em>никаких упоминаний о том, является ли значение перечисления непосредственно преобразуемым.)

person John Beyer    schedule 05.06.2013
comment
Интересный ответ, но я не уверен, что вы доказали, что перечисление можно преобразовать или нет, все, что вы доказали, это то, что Marshal.SizeOf не любит перечисления? - person Tim Lovell-Smith; 08.06.2013
comment
Интересно, что это работает: [Serializable] public enum MyConsoleColor : int { White = 0, Red = 1, Green = 2, } [StructLayout(LayoutKind.Sequential)] public struct MyStruct { public MyConsoleColor c; } static void Main(string[] args) { int t1 = Marshal.SizeOf(typeof(MyStruct)); int t2 = Marshal.SizeOf (новая MyStruct {c = MyConsoleColor.White}); } - person Tim Lovell-Smith; 08.06.2013

вместо

int enumSize = Marshal.SizeOf(Enum.GetUnderlyingType(typeof(ConsoleColor)));

ты можешь написать

int enumSize = Marshal.SizeOf(typeof(ConsoleColor).GetEnumUnderlyingType());

на самом деле первый звонит второму...

person Sven Krauter    schedule 06.02.2021