Типы значений
Ключевое слово _value (значение) похоже на _nogc (без сборки мусора), поскольку оно используется для того, чтобы класс или структура не участвовали в сборке мусора. Это полезно для определения объектов в стеке, а не в управляемой динамически распределяемой области памяти. Основная цель использования таких типов – возможность создания объектов, не требующих затрат на сборку мусора. Использование ключевого слова _value (значение) имеет побочный эффект – класс автоматически становится конечным (ключевое слово _sealed) и не может быть абстрактным (ключевое слово _abstract к нему неприменимо).
_value struct ValueStruct { int i; };
Может показаться удивительным, что правила позволяют определять тип _value (значение) там, где не позволяется определять тип _gс (сборщик мусора). В следующем фрагменте кода показан пример этого (вместе с несколькими другими конструкциями). Заметьте, что объекты классов МаnagedClass, NonManagedClass и ValueClass можно создавать в динамически распределяемой области памяти, тогда как в стек можно поместить объекты только классов NonManagedClass и ValueClass. Последний оператор во фрагменте закомментирован, так как иначе компилятор выдал бы сообщение о недопустимости объявления управляемого объекта как переменной, помещаемой в стек.
//ValueType.срр #using <mscorlib.dll> using namespace System; // использовать пространство имен Система; _nogc class NonManagedClass { }; _value class ValueClass // класс значения ValueClass { }; _gc class ManagedClass // класс сборщика мусора ManagedClass { NonManagedClass nmc; // Странно! Но для компилятора это не ошибка! ValueClass vc; // Это не ошибка, здесь допускается тип значения }; void main(void) { NonManagedClass *pnmc = new NonManagedClass; //Нет ошибки ValueClass *pvc = _nogc new ValueClass; //Нет ошибки ManagedClass *pmc = new ManagedClass; //Нет ошибки NonManagedClass; //Нет ошибки в стеке ValueClass vc; //Нет ошибки в стеке //ManagedClass me; // ошибка, не может быть размещен в стеке }