C#获取枚举值 [英] C# Getting Enum values
问题描述
我有一个包含以下内容的枚举(例如):
- 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
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屋!