2016-01-07 69 views
0

只需在Visual Studio for C++中创建CLR控制台应用程序,并复制此代码:在枚举类型的泛型类中,C++/CLI .ToString()编译失败:错误C2228:'.ToString'的左侧必须具有类/结构/联合

#include "stdafx.h" 

using namespace System; 

generic <typename TEnumMgd> 
where TEnumMgd : value class, System::ValueType, System::IConvertible 
public ref class EnumerationGenericClass 
{ 
public: 
    EnumerationGenericClass(TEnumMgd value) 
    { 
     String^ text = value.ToString(); // Cannot compile 
    } 
}; 

public enum class Test{ Foo, Bar }; 

int main(array<System::String ^> ^args) 
{ 
    auto obj = gcnew EnumerationGenericClass<Test>(Test::Foo); 
    return 0; 
} 

这种失败“错误C2228:左‘的ToString’必须有类/结构/联合”,但为什么以及如何加以解决?最好没有任何拳击。

更新:更改格式以区分问题和答案。

+0

value-> ToString()是正确的语法,您想要调用System :: Object(一个引用类型)实现的方法。您可以根据需要在MSIL中获取Opcodes.Constrained而不是Opcodes.Box。看看ildasm.exe –

+0

我猜这是因为这是在C++中唯一通用的方法。在C#中这不是问题,因为访问器总是“。”。在C++中,处理器是“。”或“ - >”取决于它的值或参考类型。对于通用类型可以是两个,所以我猜他们必须选择,因此选择“ - >”作为默认值。 – nietras

+0

@HansPassant我不想在对象上调用ToString(),但是值类型等效,但这是IL中发生的情况,因此很好。感谢您的回复。 – nietras

回答

0

这可以编译,如果你不是写:

 String^ text = value->ToString(); 

也就是说,C++/CLI使用 “ - >” 为泛型类型的访问无论是什么。然而,为ctor输出的IL在下面看到,所以它没有被装箱,但被限制为如预期的值类型。

.method public hidebysig specialname rtspecialname 
     instance void .ctor(!TEnumMgd 'value') cil managed 
{ 
    // Code size  29 (0x1d) 
    .maxstack 1 
    .locals ([0] string text) 
    IL_0000: ldnull 
    IL_0001: stloc.0 
    IL_0002: ldarg.0 
    IL_0003: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0008: ldarga.s 'value' 
    IL_000a: constrained. !TEnumMgd 
    IL_0010: callvirt instance string [mscorlib]System.ValueType::ToString() 
    IL_0015: stloc.0 
    IL_0016: ldloc.0 
    IL_0017: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_001c: ret 
} // end of method EnumerationGenericClass`1::.ctor 
相关问题