【C#】枚举类型Enum与状态设计模式
来源:互联网 发布:ae 编程 编辑:程序博客网 时间:2024/06/02 04:59
一、枚举类型Enum的基本定义与使用
本来,C#的枚举类型没什么好说的,就是刚学编程的都会,甚至还会问,这废东西还不如写一大堆常量,拿回C++那套:
public const int A = 0;public const int B = 1;public const int C = 2;
不过确实,枚举类型就是由C++传统这套拿过来的。先不说它有什么好处,至少数组化、结构体化、类化之后,枚举可以使代码更易于维护,代码更清晰,有助于确保给变量指定合法的、期望的值。同时,你还需要如下代码:
using System;using System.Collections.Generic;using System.Text;namespace Enumerate{ enum ABC { A = 0, B = 1, C, }; class Program { static void Main(string[] args) { Console.WriteLine((int)ABC.C); } }}
运行结果如下:
需要注意的是:
1、我不用再于ABC这个枚举类型enum中罗列C=2,C#会自动识别C=2的。
2、如果你要输出C=?,你必须将ABC.C转化成int。否则,如果你的代码写成这样,在输出ABC.C之前缺少一个强制类型转换的(int):
using System;using System.Collections.Generic;using System.Text;namespace Enumerate{ enum ABC { A = 0, B = 1, C, }; class Program { static void Main(string[] args) { Console.WriteLine(ABC.C); } }}
你的输出是这样的:
二、枚举类型Enum在实际编程中的简单应用
当然,上述也只是一些小问题的小打小闹。并没有看出枚举类型Enum有什么卵用,但是如果你将这个枚举类型和《【C++】状态模式》(点击打开链接)这种设计模式联系起来,则大有用途。尤其在诸如Unity3D等需要一个死循环while支撑游戏编程中,也就是那些程序不关,循环不灭的程序中,状态设计模式的思想将被采用,枚举类型Enum同样也会大放异彩。
先写个简单的。
using System;using System.Collections.Generic;using System.Text;namespace Enumerate{ enum ABC { A = 0, B = 1, C, }; class Program { static void Main(string[] args) { ABC abc = ABC.A; while (true) { switch (abc) { case ABC.A: Console.WriteLine("请输入B或者C进入状态B或者C,否则将处于状态A"); string input = Console.ReadLine(); if (input.Equals("B") || input.Equals("b")) { abc = ABC.B; } else if (input.Equals("C") || input.Equals("c")) { abc = ABC.C; } else { Console.WriteLine("还是处于状态A"); abc = ABC.A; } break; case ABC.B: Console.WriteLine("来到状态B了,输出完成~回到状态A,继续期待你的光临"); abc = ABC.A; break; case ABC.C: Console.WriteLine("来到状态C了,输出完成~回到状态A,继续期待你的光临"); abc = ABC.A; break; } } } }}
运行结果如下:
此程序的平常状态为A,随时接受用户,或者说,随时等待着用户的输入,也就是在轮询。当用户输入特定的值,或者你可以深刻理解成:一旦遇到某种条件,程序将从平常状态A转换成状态B或者C处理别的事情,处理完成再转化成平常状态A。
举这个例子,我相信已经很好地模拟出一些游戏编程中永远在循环读取的update()函数,每一个游戏帧执行的update()类似就是类似于这里的while(true),而,如果你需要在update()函数中处理一些类似游戏主角、游戏对象或者游戏状态的东西,建议利用这种状态设计模式。
通过阅读上述代码,相信大家大致能看到枚举类型Enum与内含switch~case结构的死循环while(true)配合形成的设计模式。这里,枚举组,叫做ABC,那么你就可以利用ABC a=ABC.A,来定义一个类似指向这个枚举组的指针a,先指向枚举组ABC的A,然后a=ABC.某某,就指向其它状态了,可以随心所欲在状态中切换,就可以省去一大堆,连你自己都绕翻车的if~else if ~else渣结构了。
三、枚举类型Enum与状态设计模式
以上的代码,体现了一种状态设计模式的思想,当然,虽然这类代码更常见,但是,这并不是严格的状态设计模式。如果要写一个严格的状态设计模式,同样可以用到枚举类型Enum。还是用那道2011年下半年的软件设计师软考题目再来说明:
题目是这样的:
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾,纸巾售卖机的状态图如图5-1所示:
采用状态(State)模式来实现该纸巾售卖机,得到如图5-2所示的类图,其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldOutState、NoQuarterState、HasQuarterState、SoldState分别对应图5-1纸巾售卖机的4种状态。售出纸巾、纸巾售卖、没有投币、有2元钱。
当然,这里我就不完全照抄软考题目中提供的伪代码格式了,自己用枚举类型Enum写完这个状态设计模式,满足题目的要求。
首先,你要注意到,这是一个纸巾售卖机,就算其处于待机状态,一旦有用户来用,你也要即时相应,也时刻就处于轮询状态,所以这是就考虑到先枚举几个状态,对于用户的动作,时刻做出切换,因此,代码如下,注意到void dispense();实质是TissueMachine自己的内部处理方法,不会给用户调用的。只是这里接口要求其继承者,对其所含有的方法的可访问xing
using System;namespace EnumStatePattern{ interface StateHandle { void insertQuarter();//“投币”按钮被按下 void ejectQuarter();//“退币”按钮被按下 void turnCrank();//“出纸巾”按钮被按下 void dispense();//正在售出纸巾 } class TissueMachine : StateHandle { private enum State {//自动售货机的四种可能状态 soldOutState = -1,//纸巾卖完 noQuarterState = 0,//没有投币 hasQuarterState = 1,//已有投币 soldState = 2,//正在售出 } private int money;//自动售货机当前拥有的投币数量 private State state;//自动售货机当前的状态 public TissueMachine() {//自动售货机的初始化 this.money = 0; this.state = State.noQuarterState; } public void insertQuarter() { switch (this.state) { case State.soldOutState: Console.WriteLine("纸巾已经卖完了,本纸巾自动售货机停机!"); break; case State.noQuarterState: this.money += 2; Console.WriteLine("感谢投币!当前纸巾机存有币:{0}", this.money); this.state = State.hasQuarterState; break; case State.hasQuarterState: this.money += 2; Console.WriteLine("感谢投币!当前纸巾机存有币:{0}", this.money); break; case State.soldState: Console.WriteLine("正在售出!请不要进行操作。"); break; } } public void ejectQuarter() { switch (this.state) { case State.soldOutState: Console.WriteLine("纸巾已经卖完了,本纸巾自动售货机停机!"); break; case State.noQuarterState: Console.WriteLine("投币机没有投币,无法退币!"); break; case State.hasQuarterState: this.money -= 2; Console.WriteLine("你的投币已经退回!当前纸巾机存有币:{0}", this.money); if (this.money == 0) { this.state = State.noQuarterState; } break; case State.soldState: Console.WriteLine("正在售出!请不要进行操作。"); break; } } public void turnCrank() { switch (this.state) { case State.soldOutState: Console.WriteLine("纸巾已经卖完了,本纸巾自动售货机停机!"); break; case State.noQuarterState: Console.WriteLine("请投币!"); break; case State.hasQuarterState: this.state = State.soldState; Console.WriteLine("开始售出纸巾"); dispense(); break; case State.soldState: Console.WriteLine("正在售出!请不要进行操作。"); break; } } public void dispense() { this.money -= 2; Console.WriteLine("你的纸巾,请拿好!当前纸巾机存有币:{0}", this.money); if (this.money == 0) { this.state = State.noQuarterState; } else { this.state = State.hasQuarterState; } } } class Program { static void Main(string[] args) { Console.WriteLine("输入1投币,输入2退币,输入3售出纸巾"); TissueMachine tissueMachine = new TissueMachine(); while (true) { switch (int.Parse(Console.ReadLine())) { case 1: tissueMachine.insertQuarter(); break; case 2: tissueMachine.ejectQuarter(); break; case 3: tissueMachine.turnCrank(); break; } } } }}
运行结果如下图所示:
大家可以注意到,上述代码的主函数非常非常简单,非常简单的同时,也非常清晰,用户输入什么则执行什么方法。
class Program { static void Main(string[] args) { Console.WriteLine("输入1投币,输入2退币,输入3售出纸巾"); TissueMachine tissueMachine = new TissueMachine(); while (true) { switch (int.Parse(Console.ReadLine())) { case 1: tissueMachine.insertQuarter(); break; case 2: tissueMachine.ejectQuarter(); break; case 3: tissueMachine.turnCrank(); break; } } } }
而在TissueMachine这个类当中,一开始就使用了枚举类型Enum清晰罗列了4种基本状态。
private enum State{//自动售货机的四种可能状态soldOutState = -1,//纸巾卖完noQuarterState = 0,//没有投币hasQuarterState = 1,//已有投币soldState = 2,//正在售出}
在TissueMachine接下来的各个方法中,皆使用switch~case结构,针对TissueMachine处于不同的状态而作出不同相应。用户执行某些方法,在某特定的状态的话,会发生状态转换,从而保证这个方法的顺利执行。
这样的代码写作,由于利用枚举类型Enum与状态设计模式,使得程序猿写得清晰的同时,其它维护的程序猿也清晰。彻底可以忘掉,都能把自己绕死的if~else if~else结构,吃力还不讨好。
针对TissueMachine永远在轮询用户输入的类,它注定要处于无限循环之中,所以我们要以状态划分其处理方法。此时枚举类型Enum就派上用场了。
- 【C#】枚举类型Enum与状态设计模式
- C枚举类型enum
- C枚举类型enum
- C#enum枚举类型
- 【C++】enum枚举类型
- C语言:枚举类型enum
- C语言枚举类型enum
- C语言:枚举类型enum
- C语言enum枚举类型
- C\C++ enum枚举类型
- C与C++的区别,枚举类型enum
- enum枚举类型与union联合类型
- C/C++中枚举类型(enum)
- C/C++中枚举类型(enum)
- 新手入门:C/C++中枚举类型(enum)
- C/C++中枚举类型(enum)
- C/C++中枚举类型(enum)
- [C#]Enum枚举类型使用总结
- PAT (Basic Level) Practise (中文) 1063. 计算谱半径(20)
- 数组的概念,定义格式,取值,赋值以及数组的初始化
- struts2的工作原理 及优缺点
- 跳台阶
- nginx安装,配置、虚拟主机、轮询、域名重定向
- 【C#】枚举类型Enum与状态设计模式
- 原生js和canvas实现的 柱状图、饼状图、折线图
- Python中的raw_input() 与 input()
- Machine Learning From Scratch-从头开始机器学习
- Linux进阶之 cp 命令
- 广播的最佳实践——实现强制下线功能
- 微软2017年预科生计划在线编程笔试-#1490 : Tree Restoration
- 解决eclipse add and remove 项目名带括号
- multipart/form-data请求与文件上传的细节