C++/CLI value class constraint won't compile. Why?
a few weeks ago a co-worker of mine spent about two hours finding out why this piece of C++/CLI code won't compile 开发者_开发知识库with Visual Studio 2008 (I just tested it with Visual Studio 2010... same story).
public ref class Test
{
generic<class T> where T : value class
void MyMethod(Nullable<T> nullable)
{
}
};
The compiler says: Error
1 error C3214: 'T' : invalid type argument for generic parameter 'T' of generic 'System::Nullable', does not meet constraint 'System::ValueType ^' C:\Users\Simon\Desktop\Projektdokumentation\GridLayoutPanel\Generics\Generics.cpp 11 1 Generics
Adding ValueType
will make the code compile.
public ref class Test
{
generic<class T> where T : value class, ValueType
void MyMethod(Nullable<T> nullable)
{
}
};
My question is now. Why? What is the difference between value class
and ValueType
?
P.S: See the Nullable definition for C++: http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
I analyzed the IL code of the three following methods:
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)
{
}
The corresponding IL-code, which I dissassembled with .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
{
}
This is the IL-declaration of Nullable<T>
:
.class public sequential ansi serializable sealed beforefieldinit
Nullable<valuetype (System.ValueType) .ctor T>
extends System.ValueType
As you can clearly see, only the first method's constraint matches 100% with Nullable<T>
's. (Btw: value class
seems to imply the presence of a standard constructor). However, why the compiler produces different IL-code for (semantically) the same constraints, remains still a mystery. I will ask Microsoft's C++/CLI Gurus for further information.
ValueType
is special in that it is the "base class" of value types, but not a value type itself. This is probably the issue here.
A nice list of the different entities which are used by the CLR can be found in this excellent blog post.
See also this and this thread for some more information specific to the ValueType
.
精彩评论