C#获取枚举值 [英] C# Getting Enum values

查看:85
本文介绍了C#获取枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含以下内容的枚举(例如):




  • UnitedKingdom,

  • 美国,

  • 法国,

  • 葡萄牙



在我的代码中,我使用 Country.UnitedKingdom ,但如果我将其分配给字符串,我想要的值为 UK 。 p>

这是可能吗?

解决方案

您不能指定枚举值到一个字符串开始。您必须调用 ToString(),将 Country.UnitedKingdom 转换为UnitedKingdom。



两个选项建议自己:




  • 创建一个字典<国家,string>

  • 开关语句

  • 用属性装饰每个值,并加载反射



有关每个人的评论...



code>词典<国家,字符串>

  using System; 
使用System.Collections.Generic;

enum国家
{
UnitedKingdom,
美国,
法国,
葡萄牙
}

class Test
{
static readonly Dictionary< Country,string> CountryNames =
new Dictionary< Country,string>
{
{Country.UnitedKingdom,UK},
{Country.UnitedStates,US},
};

static string ConvertCountry(国家/地区)
{
string name;
return(CountryNames.TryGetValue(country,out name))
? name:country.ToString();
}

static void Main()
{
Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
Console.WriteLine(ConvertCountry(Country.UnitedStates));
Console.WriteLine(ConvertCountry(Country.France));
}
}

你可能想把 ConvertCountry 转换为扩展方法。例如:

  //将其放在非嵌套的静态类
中public static string ToBriefName(this Country country )
{
string name;
return(CountryNames.TryGetValue(country,out name))
? name:country.ToString();
}

然后你可以写:

  string x = Country.UnitedKingdom.ToBriefName(); 

如注释所述,默认字典比较器将涉及拳击,这是非理想的。为了一次过,我会一直生活在一起,直到我发现这是一个瓶颈。如果我是为多个枚举这样做,我会写一个可重用的类。



切换语句



我同意 yshuditelu的回答,建议使用 switch 语句相对较少的情况。然而,由于每种情况都将是一个单一的陈述,我会亲自改变我的编码风格,以保持代码紧凑但可读:

  public static string ToBriefName(this Country country)
{
switch(country)
{
case Country.UnitedKingdom:returnUK;
case Country.UnitedStates:returnUS;
default:return country.ToString();
}
}

您可以添加更多的案例,巨大的,并且很容易将你的眼睛从枚举值转移到返回值。



DescriptionAttribute



点击 Rado关于 DescriptionAttribute 的代码是可重用的代码,但在这种情况下,我建议不要每次需要获取值时使用反射。我可能会编写一个通用的静态类来保存一个查找表(可能是一个字典,可能有一个自定义比较器,如注释中所述)。扩展方法不能在泛型类中定义,所以你可能会得到如下结果:

  public static class EnumExtensions 
{
public static string ToDescription< T>(此T值)其中T:struct
{
return DescriptionLookup< T> .GetDescription(value);
}

私有静态类描述Lookup< T>其中T:struct
{
static readonly Dictionary< T,string>说明;

static说明Lookup()
{
//初始化这里的描述,可能检查
// T是枚举
}

内部静态字符串GetDescription(T值)
{
字符串描述;
return Descriptions.TryGetValue(value,out description)
? description:value.ToString();
}
}
}


I have a enum containing the following (for example):

  • UnitedKingdom,
  • UnitedStates,
  • France,
  • Portugal

In my code I use Country.UnitedKingdom but I want to have the value be UK if I assign it to a string for example.

Is this possible?

解决方案

You can't assign an enum value to a string to start with. You'd have to call ToString(), which would convert Country.UnitedKingdom to "UnitedKingdom".

Two options suggest themselves:

  • Create a Dictionary<Country, string>
  • A switch statement
  • Decorate each value with an attribute, and load that with reflection

Comments about each of them...

Sample code for Dictionary<Country,string>

using System;
using System.Collections.Generic;

enum Country
{
    UnitedKingdom, 
    UnitedStates,
    France,
    Portugal
}

class Test
{
    static readonly Dictionary<Country, string> CountryNames =
        new Dictionary<Country, string>
    {
        { Country.UnitedKingdom, "UK" },
        { Country.UnitedStates, "US" },
    };

    static string ConvertCountry(Country country) 
    {
        string name;
        return (CountryNames.TryGetValue(country, out name))
            ? name : country.ToString();
    }

    static void Main()
    {
        Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
        Console.WriteLine(ConvertCountry(Country.UnitedStates));
        Console.WriteLine(ConvertCountry(Country.France));
    }
}

You might want to put the logic of ConvertCountry into an extension method. For example:

// Put this in a non-nested static class
public static string ToBriefName(this Country country) 
{
    string name;
    return (CountryNames.TryGetValue(country, out name))
        ? name : country.ToString();
}

Then you could write:

string x = Country.UnitedKingdom.ToBriefName();

As mentioned in the comments, the default dictionary comparer will involve boxing, which is non-ideal. For a one-off, I'd live with that until I found it was a bottleneck. If I were doing this for multiple enums, I'd write a reusable class.

Switch statement

I agree with yshuditelu's answer suggesting using a switch statement for relatively few cases. However, as each case is going to be a single statement, I'd personally change my coding style for this situation, to keep the code compact but readable:

public static string ToBriefName(this Country country) 
{
    switch (country)
    {
        case Country.UnitedKingdom:  return "UK";
        case Country.UnitedStates:   return "US";
        default:                     return country.ToString();
    }
}

You can add more cases to this without it getting too huge, and it's easy to cast your eyes across from enum value to the return value.

DescriptionAttribute

The point Rado made about the code for DescriptionAttribute being reusable is a good one, but in that case I'd recommend against using reflection every time you need to get a value. I'd probably write a generic static class to hold a lookup table (probably a Dictionary, possibly with a custom comparer as mentioned in the comments). Extension methods can't be defined in generic classes, so you'd probably end up with something like:

public static class EnumExtensions
{
    public static string ToDescription<T>(this T value) where T : struct
    {
        return DescriptionLookup<T>.GetDescription(value);
    }

    private static class DescriptionLookup<T> where T : struct
    {
        static readonly Dictionary<T, string> Descriptions;

        static DescriptionLookup()
        {
            // Initialize Descriptions here, and probably check
            // that T is an enum
        }

        internal static string GetDescription(T value)
        {
            string description;
            return Descriptions.TryGetValue(value, out description)
                ? description : value.ToString();
        }
    }
}

这篇关于C#获取枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆