Enums C+中类似于枚举描述属性的C+/CLI

Enums C+中类似于枚举描述属性的C+/CLI,enums,c++-cli,Enums,C++ Cli,C#允许以下功能显示用户友好的Enum版本。类型转换器接受description属性并使用它生成字符串。这可以在C++/CLI中完成吗?据我所见,“公共枚举类”不能在枚举成员上具有属性。这意味着我不能为每个枚举定义描述属性内容。如何定义友好名称 [TypeConverter(typeof(EnumDescriptionConverter))] public enum MyEnum { [Description("Item1")] Item1, [Description("

C#允许以下功能显示用户友好的Enum版本。类型转换器接受description属性并使用它生成字符串。这可以在C++/CLI中完成吗?据我所见,“公共枚举类”不能在枚举成员上具有属性。这意味着我不能为每个枚举定义描述属性内容。如何定义友好名称

[TypeConverter(typeof(EnumDescriptionConverter))]
public enum MyEnum
{
    [Description("Item1")]
    Item1,
    [Description("Item2")]
    Item2, 
}

class EnumDescriptionConverter : EnumConverter
{
    private Type _enumType;
    public EnumDescriptionConverter(Type type)
        : base(type)
    {
        _enumType = type;
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
    {
        return destType == typeof(string);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
    {
        String ReturnString = "";

        if (_enumType.GetCustomAttributes<FlagsAttribute>().Any())
        {
            foreach (var val in EnumExtensions.GetIndividualFlags((Enum)value))
            {
                FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, val));
                DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));

                if (ReturnString != "")
                    ReturnString += " | ";

                if (dna != null)
                    ReturnString += dna.Description;
                else
                    ReturnString += val.ToString();
            }
        }
        else
        {
            FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, value));
            DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));

            if (ReturnString != "")
                ReturnString += " | ";

            if (dna != null)
                ReturnString += dna.Description;
            else
                ReturnString += value.ToString();
        }
        return ReturnString;
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
    {
        return srcType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        foreach (FieldInfo fi in _enumType.GetFields())
        {
            DescriptionAttribute dna =
            (DescriptionAttribute)Attribute.GetCustomAttribute(
            fi, typeof(DescriptionAttribute));

            if ((dna != null) && ((string)value == dna.Description))
                return Enum.Parse(_enumType, fi.Name);
        }
        return Enum.Parse(_enumType, (string)value);
    }
}
[TypeConverter(typeof(EnumDescriptionConverter))]
公共枚举髓鞘
{
[说明(“第1项”)]
项目1,
[说明(“第2项”)]
项目2,
}
类EnumDescriptionConverter:EnumConverter
{
私有类型_enumType;
公共EnumDescriptionConverter(类型)
:基本(类型)
{
_枚举类型=类型;
}
公共覆盖布尔CanConvertTo(ITypeDescriptorContext上下文,类型destType)
{
返回destType==typeof(字符串);
}
公共重写对象转换为(ITypeDescriptorContext上下文,CultureInfo区域性,对象值,类型destType)
{
字符串ReturnString=“”;
if(_enumType.GetCustomAttributes().Any())
{
foreach(EnumExtensions.GetIndividualFlags((Enum)值)中的var val)
{
FieldInfo fi=_enumType.GetField(Enum.GetName(_enumType,val));
DescriptionAttribute dna=(DescriptionAttribute)属性.GetCustomAttribute(fi,typeof(DescriptionAttribute));
如果(返回字符串!=“”)
ReturnString+=“|”;
如果(dna!=null)
ReturnString+=dna.Description;
其他的
ReturnString+=val.ToString();
}
}
其他的
{
FieldInfo fi=_enumType.GetField(Enum.GetName(_enumType,value));
DescriptionAttribute dna=(DescriptionAttribute)属性.GetCustomAttribute(fi,typeof(DescriptionAttribute));
如果(返回字符串!=“”)
ReturnString+=“|”;
如果(dna!=null)
ReturnString+=dna.Description;
其他的
ReturnString+=value.ToString();
}
返回字符串;
}
公共覆盖布尔CanConvertFrom(ITypeScriptorContext上下文,类型srcType)
{
返回srcType==typeof(字符串);
}
公共重写对象ConvertFrom(ITypeDescriptorContext上下文、CultureInfo区域性、对象值)
{
foreach(在_enumType.GetFields()中的FieldInfo fi)
{
描述属性dna=
(DescriptionAttribute)Attribute.GetCustomAttribute(
fi,类型(描述属性));
if((dna!=null)&&((字符串)值==dna.Description))
返回Enum.Parse(_enumType,fi.Name);
}
返回Enum.Parse(_enumType,(string)值);
}
}

在进一步研究之后,我求助于下面的类型转换器。它只是将枚举成员中的下划线替换为空格。它还可以处理标志

ref class EnumDescriptionConverter : public System::ComponentModel::EnumConverter
{
private:
    System::Type^ _enumType;
public:
    EnumDescriptionConverter(System::Type^ type) : System::ComponentModel::EnumConverter(type)
    {
        _enumType = type;
    }

    bool CanConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ destType)override
    {
        return destType == System::String::typeid;
    }

    System::Object^ ConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value, System::Type^ destType)override
    {
        return value->ToString()->Replace("_", " ");
    }

    bool CanConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ srcType)override
    {
        return srcType == System::String::typeid;
    }

    System::Object^ ConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value)override
    {
        return System::Enum::Parse(_enumType, ((System::String^)value)->Replace(" ", "_")->Replace(",_", ", "));
    }
};
枚举的定义如下:

[System::ComponentModel::TypeConverter(typeof(EnumDescriptionConverter))]
public enum class MyEnum
{
    Item_1, // Appears as 'Item 1' when data bound or in a property grid
    Item_2  // Appears as 'Item 2' when data bound or in a property grid
}

您已经打破了堆栈溢出问题的基本规则:您实际上没有包含真正的源代码或确切的错误消息

这段代码在Visual Studio 2013的全新C++/CLI控制台应用程序项目中编译得非常好:

using System::ComponentModel::DescriptionAttribute;

public enum class MyEnum
{
    [Description("Item1")]
    Item1,
    [Description("Item2")]
    Item2, 
};

C++11对C++/CLI不是很友好,它采用了
enum类
。[Description]属性仍在编译,但IntelliSense解析器无法处理它们。否则,在
数组^lookup=gcnew数组{“foo”、“bar”、“baz}中进行简单查找
您的实际代码是否确实包含
公共枚举类
,而不仅仅是
枚举类
?前者是C++/CLI maanged类型,后者是C++11作用域的枚举。这不适合我编译。Intellisense突出显示开始括号
[
,并给出消息“错误:需要一个标识符。”@RussellTrahan:您是使用
/clr
编译的吗?什么版本的Visual Studio?编译器错误是什么?Intellisense不是后台编译,它是一个源代码浏览器,用于处理无法编译的代码,因为代码仍在编辑中。请仅信任实际的编译器错误。确定。它确实编译,但提供Intellisensese错误。我正在使用/clr和VS2013。如果它是有效代码,为什么intellisense会不喜欢它?@RussellTrahan:Hans告诉过你有一个intellisense bug什么,大约3个小时前?当你碰巧看到“非法使用此类型作为表达式”错误时,请确保你没有使用
类型(EnumDescriptionConverter)
但是
枚举描述转换器::类型ID