несколько недель назад мой коллега провел приблизительно два часа, узнавая, почему эта часть C++ / код CLI не скомпилирует с Visual Studio 2008 (я просто протестировал его с Visual Studio 2010... та же история).
public ref class Test
{
generic where T : value class
void MyMethod(Nullable nullable)
{
}
};
В компиляторе говорится: Ошибка
1 ошибка C3214: 'T': недопустимый аргумент типа для универсального параметра 'T' универсальной 'Системы:: Nullable', не встречает ограничение 'Система:: ValueType ^' C:\Users\Simon\Desktop\Projektdokumentation\GridLayoutPanel\Generics\Generics.cpp 11 1 Дженерик
Добавление ValueType
сделает компиляцию кода.
public ref class Test
{
generic where T : value class, ValueType
void MyMethod(Nullable nullable)
{
}
};
Мой вопрос теперь. Почему? Между чем различие value class
и ValueType
?
P.S.: См. определение Nullable для C++: http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
Я проанализировал IL-код трех следующих методов:
generic<class T> where T : value class, System::ValueType
static void MyMethod(T arg)
{
}
generic<typename T> where T: value class
static void MyMethod2(T arg)
{
}
generic<typename T> where T: ValueType
static void MyMethod3(T arg)
{
}
Соответствующий IL-код, который я разобрал с помощью .NET-Reflector:
.method public hidebysig
static void MyMethod<valuetype ([mscorlib]System.ValueType).ctor T>
(!!T arg) cil managed
{
}
.method public hidebysig
static void MyMethod2<valuetype .ctor T>(!!T arg) cil managed
{
}
.method public hidebysig
static void MyMethod3<([mscorlib]System.ValueType) T>(!!T arg) cil managed
{
}
Это IL-объявление Nullable
:
.class public sequential ansi serializable sealed beforefieldinit
Nullable<valuetype (System.ValueType) .ctor T>
extends System.ValueType
Как вы можете ясно видеть, только ограничение первого метода на 100% совпадает с Nullable
. (Кстати: класс значений
, похоже, подразумевает наличие стандартного конструктора). Однако почему компилятор выдает разный IL-код для (семантически) одних и тех же ограничений, остается загадкой. Я спрошу у гуру Microsoft C ++ / CLI дополнительную информацию.
ValueType
является особенным в том смысле, что это «базовый класс» типов значений, но не сам тип значения. Вероятно, в этом проблема.
Хороший список различных сущностей, которые используются CLR, можно найти в этой замечательной записи блога .
См. Также этот и этот поток для получения дополнительной информации о ValueType
.