Просто создайте консольное приложение CLR в Visual Studio для C++ и скопируйте этот код :Ошибка компиляции C++/CLI .ToString() в универсальном классе для типов перечисления: ошибка C2228: слева от '.ToString' должен быть класс/struct/union
#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“должен иметь класс/структуры/объединения», но почему и как это можно решить? Предпочтительно без бокса.
UPDATE: Изменен формат для разделения вопросов и ответов.
value-> ToString() - это правильный синтаксис, который вы хотите вызвать методом, реализованным System :: Object, ссылочным типом. Вы получаете Opcodes.Constrained вместо Opcodes.Box в MSIL, как хотите. Посмотрите на это с помощью ildasm.exe –
Я предполагаю, что это потому, что это был единственный общий способ сделать этот родовой код на C++. В C# это не проблема, потому что аксессор всегда «.». В C++ ацессор либо «.» или "->" в зависимости от этого значения или типа ref. Для общего типа тип может быть таким, поэтому я предполагаю, что им нужно было выбрать и, таким образом, выбрать «->» по умолчанию. – nietras
@HansPassant хорошо Я не хочу вызывать ToString() на объекте, но тип значения эквивалентен, но это то, что происходит в IL, так что это нормально. Спасибо за ваш ответ. – nietras