标签:console 关键字 计算 静态 存在 例子 OLE 声明 表示
枚举是 C# 中最有意思的一部分,大部分开发人员只了解其中的一小部分,甚至网上绝大多数的教程也只讲解了枚举的一部分。那么,我将通过这篇文章向大家具体讲解一下枚举的知识。我将从大家都了解的部分开始讲解,然后再讲解大家所不知道的或者了解很少的部分。
枚举是由开发人员声明的一种 值类型 ,它在编译时就声明了一种 具名常量值 。使用枚举可以使我们的代码简单易读,我们先来看一下两个代码段:
// 代码段 1
void Method(int country)
{
switch (country)
{
case 0:
// more code
break;
case 1:
// more code
break;
case 2:
// more code
break;
case 3:
// more code
break;
default:
// more code
break;
}
}
// 代码段 2
void Method(Country country)
{
switch (country)
{
case Country.CN:
// more code
break;
case Country.JP:
// more code
break;
case Country.UK:
// more code
break;
case Country.USA:
// more code
break;
default:
// more code
break;
}
}
从上面的两个代码段我们可以看到两者有明显的区别。第一段代码中的 case 值我们几乎完全不知道代表了什么是什么意思,但是第二段代码我们使用了枚举,通过 case 值马上就可以知道所要表达的意思。同样利用枚举值替代布尔值也可以改善代码的可读性,例如我们要开发控制台灯打开关闭的程序,代码可以这么写 LightOperating(True)
,但是这种代码我们无法看出具体要干什么,现在我们将代码改动一下 LightOperating(Light.On)
。经过修改代码就很容易看出所要表达的意思。
枚举定义与取值
定义枚举有两种方式,分别是普通方式和自定义方式。不管使用哪种方式都需要用的关键字 enum 来标识这个类型为枚举类型,并且枚举值都是作为整数常量来实现的。下面我们就来看一下这两种方式怎么定义枚举的。普通方式是我们经常用到的,也是默认的方式。这种方式很简单,代码如下:
enum Country
{
CN,
UK,
JP,
USA
}
在上面的代码段中我们定义了一个国家枚举,第一个枚举值对应的整数常量是 0 ,第二个枚举值对应的整数常量是 1 ,以此类推后面的枚举值分别对应的整数常量是 2 和 3 。但是在部分情况下我们需要自定义枚举值对应的整数常量,这个时候我们就需要用到自定义的方式。自定义方式又称为为枚举值显式赋值,它的方法如下所示:
enum Country
{
CN = 3,
UK,
JP = 70,
USA = 67
}
我们在代码中将第一个枚举值对应的整数常量设置为了 3 ,这时第二个枚举值的整数常量就不是 1 了,而是 4 ,因为当枚举值没有显示赋值时,将会按照上一个枚举值对应的整数值加 1 来作为自己本身对应的整数值。最后两个枚举值因为显式赋值了因此对应的整数值就是所赋值的数值。
枚举取值也很简单,只需要 枚举名.枚举值 即可,例如 Country.UK
。
Tip:这里我提几点建议:
枚举的类型
到目前为止我们定义枚举类型使用的基础类型 int 类型,但是枚举不仅仅可以使用 int 类型,还可以使用除了 char 类型之外的所有基础类型。我们可以使用继承语法来指定其他类型。
enum Country:short
{
CN = 3,
UK,
JP = 70,
USA = 67
}
上面代码中我们显式定义了枚举所使用的基础类型为 short 。这里虽然使用了继承语法但是并没有建立继承关系,所有的枚举基类都是 System.Enum ,这些类都是密封类,无法从现有的枚举类型派生出新的成员。
对于枚举类型的变量,值不限于声明中命名的值,因此值能转换成基础类型,那么就能转换为枚举类型。之所以这么设计是因在以后的 API 中有很大的可能在不破换老版本的同时为枚举添加新的值。但是这其中也存在一个缺陷,枚举允许在运行时分配未知的值,对于这一点我们在开发时需要考虑到。并且在后期向枚举中添加新的枚举值时应将其添加到所有枚举值的后面,或者显示指定枚举值对应的数值,这样才能避免因添加新值导致枚举类型中的枚举值对应的数值改变。
Tip:在开发中我们应该尽量使用 int 作为枚举的基础类型,除非因性能问题或互操作方面的考虑时才会考虑使用较小的类型。
枚举转换主要涉及到了枚举与枚举的转换、枚举与数字和字符串的转换。
static void Main(string[] args)
{
CountryAllName[] can = (CountryAllName[])(Array)new Country[4];
}
enum Country
{
CN,
UK,
JP,
USA
}
enum CountryAllName
{
China,
UnitedKingdom,
Japan,
UnitedStates
}
在使用这种方法时有可能会出现意外的错误或结果,并且相关开发规范中并没有说这种方式每次都起作用,因此我不建议这么使用,除非在一些极端场景中。Country.CN.ToString()
得到的结果是字符串 CN 。当然,你也可以利用 Enum.GetNames 和 Enum.GetName 方法来获取。下面我简单来讲解一下这两个方法的使用。
Enum.GetNames(typeof(Country))[1]
,返回结果是 UK 。Enum.GetName(typeof(Country),1)
,返回的值同样是 UK 。(Country)Enum.Parse(typeof(Country),"JP")
。这里有一点需要注意,TryParse 方法是在 .net 4.0 才出现的,因此如果要在 .net 4.0 以下版本中将字符串转换为枚举时,需要进行恰当的错误处理防止字符串不存在与枚举类型中的枚举值中。Tip:字符串向枚举转换不可本地化,如果必须本地化,就必须是那些对上层用户不可见的消息。因此在实际开发中应该尽量避免枚举和字符串之间的转换。
(int)Country.CN
返回结果是 0 。从数字转换为枚举我们有两种方法,一种是使用强转,另一种是使用 Enum 的静态方发 ToObject 。
Country country = (Country)2
Country country = (Country)Enum.ToObject(typeof(Country),2)
Type type = typeof(Country);
if(Enum.IsDefined(type,0))
{
Enum.ToObject(type, 0);
}
if(Enum.IsDefined(type,"HK"))
{
Enum.Parse(typeof(Country), "HK");
}
上述代码中只有 0 会成功转换为枚举值 CN ,因为 0 所对应的枚举值是 CN ,而 HK 并没有在枚举中。这一小节我们来讲解一下标志与属性,标志和属性属于在开发中用的比较少,并且大部分程序员了解的也不多。
[Flags]
enum WeekDays
{
Monday = 1,
Tuesday = 2,
Wednesday = 4,
Thursday = 8,
Friday = 16,
Saturday = 32,
Sunday = 64
}
在上面的代码中你会发现一个规律,每个枚举值对应的整数值都是 2的n次方,这是为什么呢。在标志枚举中要求多个枚举值相互组合后的结果不能包含在标志枚举中,并且基于按位运算的特性可以很方便的使用位运算符来计算一个枚举值是否包含了另外一个枚举值,这在权限系统中相当有用。public class EnumChineseAttribute : Attribute
{
private string m_strDescription;
public EnumChineseAttribute(string chineseName)
{
m_strDescription = chineseName;
}
public string Description
{
get { return m_strDescription; }
}
}
enum Country
{
[EnumChinese("中国")]
CN,
[EnumChinese("英国")]
UK,
[EnumChinese("日本")]
JP,
[EnumChinese("美国")]
USA
}
static void Main(string[] args)
{
Country country = Country.CN;
FieldInfo fieldInfo = country.GetType().GetField("CN");
object[] attribArray = fieldInfo.GetCustomAttributes(false);
EnumChineseAttribute attrib = (EnumChineseAttribute)attribArray[0];
Console.WriteLine(attrib.Description);
Console.Read();
}
通过上面的代码我们就能获取到 CN 对应的中文名称了,这段代码并没有进行进一步优化,在实际项目中必须进行封装和优化。这篇文章主要讲解了枚举相关的知识,内容有点琐碎,但是在实际开发中还是比较实用的。文章中我所提到的要点和规定在实际开发中已经经过验证,各位读者可以直接拿来使用。
本文由博客一文多发平台 OpenWrite 发布!
标签:console 关键字 计算 静态 存在 例子 OLE 声明 表示
原文地址:https://www.cnblogs.com/treeskyer/p/12726060.html