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

C# like enum desciption attributes in C++/CLI

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

[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);
    }
}

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

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
}

您违反了 Stack Overflow 问题的基本规则:您实际上没有包含真正的源代码或确切的错误消息。

此代码在 Visual Studio 2013 年的全新 C++/CLI 控制台应用程序项目中对我来说编译得很好:

using System::ComponentModel::DescriptionAttribute;

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