几周前,我的一个同事花了大约两个小时找出为什么这段 C++/CLI 代码不能用 Visual Studio 2008 编译(我刚刚用 Visual Studio 2010 测试过……同样的故事)。
public ref class Test
{
generic<class T> where T : value class
void MyMethod(Nullable<T> nullable)
{
}
};
编译器说:错误
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
添加
ValueType
将使代码编译。public ref class Test
{
generic<class T> where T : value class, ValueType
void MyMethod(Nullable<T> nullable)
{
}
};
我的问题是现在。为什么?
value class
有什么区别和 ValueType
?P.S:请参阅 C++ 的 Nullable 定义: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
{
}
这是
Nullable<T>
的 IL 声明:.class public sequential ansi serializable sealed beforefieldinit
Nullable<valuetype (System.ValueType) .ctor T>
extends System.ValueType
如您所见,只有第一种方法的约束与
Nullable<T>
100% 匹配。的。 (顺便说一句:value class
似乎暗示存在标准构造函数)。然而,为什么编译器为(语义上)相同的约束产生不同的 IL 代码,仍然是个谜。我会向 Microsoft 的 C++/CLI Gurus 询问更多信息。
关于generics - C++/CLI 值类约束将无法编译。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2843932/