2016-01-07 61 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 
相關問題