Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 772
Simon Avatar asked May 16 '10 13:05

Simon


1 Answers

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.

like image 180
Simon Avatar answered Sep 22 '22 10:09

Simon