如何从值中获取 C# Enum 描述?

发布于 2024-08-29 06:14:58 字数 941 浏览 3 评论 0原文

我有一个带有如下描述属性的枚举:

public enum MyEnum
{
    Name1 = 1,
    [Description("Here is another")]
    HereIsAnother = 2,
    [Description("Last one")]
    LastOne = 3
}

我发现了这段用于基于枚举检索描述的代码

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

    if (attributes != null && attributes.Any())
    {
        return attributes.First().Description;
    }

    return value.ToString();
}

这允许我编写如下代码:

var myEnumDescriptions = from MyEnum n in Enum.GetValues(typeof(MyEnum))
                         select new { ID = (int)n, Name = Enumerations.GetEnumDescription(n) };

我想要做的是如果我知道枚举值(例如 1) - 如何我可以检索描述吗?换句话说,如何将整数转换为“枚举值”以传递给我的 GetDescription 方法?

I have an enum with Description attributes like this:

public enum MyEnum
{
    Name1 = 1,
    [Description("Here is another")]
    HereIsAnother = 2,
    [Description("Last one")]
    LastOne = 3
}

I found this bit of code for retrieving the description based on an Enum

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

    if (attributes != null && attributes.Any())
    {
        return attributes.First().Description;
    }

    return value.ToString();
}

This allows me to write code like:

var myEnumDescriptions = from MyEnum n in Enum.GetValues(typeof(MyEnum))
                         select new { ID = (int)n, Name = Enumerations.GetEnumDescription(n) };

What I want to do is if I know the enum value (e.g. 1) - how can I retrieve the description? In other words, how can I convert an integer into an "Enum value" to pass to my GetDescription method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

困倦 2024-09-05 06:14:59
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

C# 中 enum 的默认基础数据类型是 int,您可以直接转换它。

int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

The default underlying data type for an enum in C# is an int, you can just cast it.

猫七 2024-09-05 06:14:59

更新

Unconstrained Melody 库不再维护;放弃支持,转而支持 Enums.NET

在 Enums.NET 中,您可以使用:

string description = ((MyEnum)value).AsString(EnumFormat.Description);

原始帖子

我以通用的、类型安全的方式在 Unconstrained Melody 中实现了这一点 - 你会使用:

string description = Enums.GetDescription((MyEnum)value);

这:

  • 确保(带有泛型类型约束)该值确实是一个枚举值
  • 避免当前解决方案中的装箱
  • 缓存所有描述以避免在每次调用时使用反射
  • 还有一堆其他方法,包括从描述中解析值的能力

我意识到核心答案只是从 intMyEnum 的转换,但如果你做了很多枚举工作值得考虑使用 Unconstrained Melody :)

Update

The Unconstrained Melody library is no longer maintained; Support was dropped in favour of Enums.NET.

In Enums.NET you'd use:

string description = ((MyEnum)value).AsString(EnumFormat.Description);

Original post

I implemented this in a generic, type-safe way in Unconstrained Melody - you'd use:

string description = Enums.GetDescription((MyEnum)value);

This:

  • Ensures (with generic type constraints) that the value really is an enum value
  • Avoids the boxing in your current solution
  • Caches all the descriptions to avoid using reflection on every call
  • Has a bunch of other methods, including the ability to parse the value from the description

I realise the core answer was just the cast from an int to MyEnum, but if you're doing a lot of enum work it's worth thinking about using Unconstrained Melody :)

李白 2024-09-05 06:14:59

我将代码从通用扩展方法中接受的答案中组合在一起,因此它可以用于所有类型的对象:

public static string DescriptionAttr<T>(this T source)
{
    FieldInfo fi = source.GetType().GetField(source.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0) return attributes[0].Description;
    else return source.ToString();
}

使用原始帖子中的枚举,或任何其他其属性用 Description 属性装饰的类,代码可以这样消费:

string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();

I put the code together from the accepted answer in a generic extension method, so it could be used for all kinds of objects:

public static string DescriptionAttr<T>(this T source)
{
    FieldInfo fi = source.GetType().GetField(source.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0) return attributes[0].Description;
    else return source.ToString();
}

Using an enum like in the original post, or any other class whose property is decorated with the Description attribute, the code can be consumed like this:

string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();
丑丑阿 2024-09-05 06:14:59

为了使其更易于使用,我编写了一个通用扩展:

public static string ToDescription<TEnum>(this TEnum EnumValue) where TEnum : struct
{
    return Enumerations.GetEnumDescription((Enum)(object)((TEnum)EnumValue));
}

现在我可以编写:

        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);

注意:将上面的“枚举”替换为您的类名

To make this easier to use, I wrote a generic extension:

public static string ToDescription<TEnum>(this TEnum EnumValue) where TEnum : struct
{
    return Enumerations.GetEnumDescription((Enum)(object)((TEnum)EnumValue));
}

now I can write:

        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);

Note: replace "Enumerations" above with your class name

海未深 2024-09-05 06:14:59

您无法轻松地以通用方式执行此操作:您只能将整数转换为特定类型的枚举。正如 Nicholas 所示,如果您只关心一种枚举,那么这是一个微不足道的转换,但如果您想编写一个可以处理不同类型枚举的泛型方法,事情就会变得有点复杂。您需要一个类似于以下内容的方法:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}

但这会导致编译器错误“int 无法转换为 TEnum”(如果您解决此问题,则“TEnum 无法转换为 Enum”)。因此,您需要通过向对象插入强制转换来欺骗编译器:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)(object)((TEnum)(object)value));  // ugly, but works
}

您现在可以调用它来获取手头任何类型的枚举的描述:

GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);

You can't easily do this in a generic way: you can only convert an integer to a specific type of enum. As Nicholas has shown, this is a trivial cast if you only care about one kind of enum, but if you want to write a generic method that can handle different kinds of enums, things get a bit more complicated. You want a method along the lines of:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}

but this results in a compiler error that "int can't be converted to TEnum" (and if you work around this, that "TEnum can't be converted to Enum"). So you need to fool the compiler by inserting casts to object:

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)(object)((TEnum)(object)value));  // ugly, but works
}

You can now call this to get a description for whatever type of enum is at hand:

GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文