2010-05-16 63 views
6

几周前,我的一位同事花了大约两个小时的时间来了解为什么这段C++/CLI代码不能用Visual Studio 2008进行编译(我刚刚用Visual Studio 2010进行了测试......同样的故事)。C++/CLI的值类约束不会被编译。为什么?

​​

编译器说:错误

1错误C3214: 'T':无效类型 论据泛型参数 通用的 'T' '系统::可空',不符合 约束 '系统:值类型 ^' C:\用户\西蒙\桌面\ Projektdokumentation \ GridLayoutPanel \泛型\ Generics.cpp 111个泛型

添加ValueType将使代码编译。

public ref class Test 
{ 
    generic<class T> where T : value class, ValueType 
     void MyMethod(Nullable<T> nullable) 
    { 

    } 
}; 

我的问题是现在。为什么? value classValueType之间的区别是什么?

P.S:见可空定义C++:http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx

+0

我同意,值类约束应该已经足够了。我认为你的解决方法是正确的。你可以尝试connect.microsoft.com看看他们会说些什么。 – 2010-05-16 17:02:43

回答

5

我分析了下列三种方法的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的反射dissassembled:

.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<T>

.class public sequential ansi serializable sealed beforefieldinit 
Nullable<valuetype (System.ValueType) .ctor T> 
    extends System.ValueType 

正如你可以清楚地看到,只有第一个方法的约束与Nullable<T>的100%匹配。 (顺便说一句:value class似乎暗示存在一个标准的构造函数)。但是,为什么编译器为(语义)相同的约束条件生成不同的IL代码,仍然是一个谜。我会询问微软的C++/CLI大师了解更多信息。

0

ValueType之处在于它是“基类”值类型的,但不是一个值类型本身特殊。这可能是这里的问题。

CLR使用的不同实体的好列表可以在this excellent blog post中找到。

另请参阅thisthis thread了解关于ValueType的更多信息。

+0

感谢您的研究,Lucero。 – Simon 2010-05-16 18:58:01