亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

一個狀態機的實現

2019-10-29 21:14:47
字體:
來源:轉載
供稿:網友

話不多說,先看代碼:

interface IState {  string Name { get; set; }  //后件處理  IList<IState> Nexts { get; set; }  Func<IState /*this*/, IState /*next*/> Selector { get; set; }   } class State : IState {  public string Name { get; set; } = "State";  IList<IState> IState.Nexts { get; set; } = new List<IState>();  public Func<IState, IState> Selector { get; set; } }

狀態比較簡單,一個Name標識,一個后件狀態列表,然后一個狀態選擇器。

比如狀態a,可以轉移到狀態b,c,d,那么選擇器就是其中一個。至于怎么選,就讓用戶來定義實際的選擇器了。

delegate bool HandleType<T>(IState current, IState previous,ref T value); interface IContext<T> : IEnumerator<T>, IEnumerable<T> {  //data  T Value { get; set; }  //前件處理  IDictionary<Tuple<IState/*this*/, IState/*previous*/>, HandleType<T>> Handles { get; set; }  IState CurrentState { get; set; }  bool transition(IState next); }

和狀態類State關注后件狀態不同,上下文類Context關注前件狀態。當跳轉到一個新的狀態,這個過程中就要根據當前狀態來實施不同的策略。比如想進入狀態c,根據當前狀態是a, b,d 有不同的處理程序。這種轉移處理程序,是一一對應的,所以用了 Tuple<進入的狀態,當前狀態> 來描述一個跳轉鏈。然后用Dictionary 捆綁相關的處理程序。

上下文會攜帶 T Value 數據,要怎么處理這種數據?我是通過ref 參數來傳遞給處理程序。因為我不想IState 關心上下文的構造,它只需要關注實際的數據 T value;

上下文保存數據和當前狀態,然后通過transiton 讓用戶控制狀態的轉移。這里面有一個重復,因為IState有選擇器來控制狀態轉移了。為什么要這么處理?我是為了構造一個跳轉序列。引入IEnumerator和IEnumerable接口,然狀態可以在選擇器的作用下自動跳轉,然后用foreach 讀取結果序列(只是不知道有什么用)。

class Context<T> : IContext<T> {  T data;  T IContext<T>.Value { get=>data ; set=>data = value; }  IDictionary<Tuple<IState, IState>, HandleType<T>> IContext<T>.Handles { get; set; }    = new Dictionary<Tuple<IState, IState>, HandleType<T>>();  public IState CurrentState { get; set;}  T IEnumerator<T>.Current => (this as IContext<T>).Value ;  object IEnumerator.Current => (this as IContext<T>).Value;  bool IContext<T>.transition(IState next)  {   IContext<T> context= this as IContext<T>;   if (context.CurrentState == null || context.CurrentState.Nexts.Contains(next))   {    //前件處理    var key = Tuple.Create(next, context.CurrentState);    if (context.Handles.ContainsKey(key) && context.Handles[key] !=null)     if (!context.Handles[key](next, context.CurrentState,ref this.data))      return false;    context.CurrentState = next;    return true;   }   return false;  }  bool IEnumerator.MoveNext()  {   //后件處理   IContext<T> context = this as IContext<T>;   IState current = context.CurrentState;    if (current == null)    throw new Exception("必須設置初始狀態");   if (context.CurrentState.Selector != null)   {    IState next= context.CurrentState.Selector(context.CurrentState);    return context.transition(next);   }   return false;  }  void IEnumerator.Reset()  {   throw new NotImplementedException();  }  #region IDisposable Support  private bool disposedValue = false; // 要檢測冗余調用  protected virtual void Dispose(bool disposing)  {   if (!disposedValue)   {    if (disposing)    {     // TODO: 釋放托管狀態(托管對象)。    }    // TODO: 釋放未托管的資源(未托管的對象)并在以下內容中替代終結器。    // TODO: 將大型字段設置為 null。    disposedValue = true;   }  }  // TODO: 僅當以上 Dispose(bool disposing) 擁有用于釋放未托管資源的代碼時才替代終結器。  // ~Context() {  // // 請勿更改此代碼。將清理代碼放入以上 Dispose(bool disposing) 中。  // Dispose(false);  // }  // 添加此代碼以正確實現可處置模式。  void IDisposable.Dispose()  {   // 請勿更改此代碼。將清理代碼放入以上 Dispose(bool disposing) 中。   Dispose(true);   // TODO: 如果在以上內容中替代了終結器,則取消注釋以下行。   // GC.SuppressFinalize(this);  }  IEnumerator<T> IEnumerable<T>.GetEnumerator()  {   return this;  }  IEnumerator IEnumerable.GetEnumerator()  {   return this;  }  #endregion }

重點關注transition函數和MoveNext函數。

bool IContext<T>.transition(IState next)  {   IContext<T> context= this as IContext<T>;   if (context.CurrentState == null || context.CurrentState.Nexts.Contains(next))   {    //前件處理    var key = Tuple.Create(next, context.CurrentState);    if (context.Handles.ContainsKey(key) && context.Handles[key] !=null)     if (!context.Handles[key](next, context.CurrentState,ref this.data))      return false;    context.CurrentState = next;    return true;   }   return false;  }

做的事也很簡單,就是調用前件處理程序,處理成功就轉移狀態,否則退出。

bool IEnumerator.MoveNext()  {   //后件處理   IContext<T> context = this as IContext<T>;   IState current = context.CurrentState;    if (current == null)    throw new Exception("必須設置初始狀態");   if (context.CurrentState.Selector != null)   {    IState next= context.CurrentState.Selector(context.CurrentState);    return context.transition(next);   }   return false;  }

MoveNext通過選擇器來選擇下一個狀態。

總的來說,我這個狀態機的實現只是一個框架,沒有什么功能,但是我感覺是比較容易編寫狀態轉移目錄樹的。

用戶首先要創建一組狀態,然后建立目錄樹結構。我的實現比較粗糙,因為用戶要分別構建目錄樹,前件處理器,還有后件選擇器這三個部分。編寫測試代碼的時候,我寫了9個狀態的網狀結構,結果有點眼花繚亂。要是能統一起來估計會更好一些。

要關注的是第一個狀態,和最后的狀態的構造,否則無法停機,嵌入死循環。

//測試代碼//---------創建部分---------string mess = "";//3   IState s3 = new State() { Name = "s3" };//2   IState s2 = new State() { Name = "s2" };//1   IState s1 = new State() { Name = "s1" };//---------組合起來---------   s1.Nexts = new List<IState> { s2, s3 };   s2.Nexts = new List<IState> { s1, s3 };   s3.Nexts = new List<IState> { }; //注意end寫法//---------上下文---------    //transition   IContext<int> cont = new Context<int> { CurrentState=s1};//begin   cont.Value = 0;//---------狀態處理器--------- HandleType<int> funcLaji = (IState current, IState previous, ref int v) => { mess += $"{current.Name}:垃圾{previous.Name}/n"; v++; return true; };//1   cont.Handles.Add(Tuple.Create(s1 , default(IState)), funcLaji);   cont.Handles.Add(Tuple.Create(s1, s2), funcLaji);//2   cont.Handles.Add(Tuple.Create(s2, s1), funcLaji);//3   cont.Handles.Add(Tuple.Create(s3, s1), funcLaji); cont.Handles.Add(Tuple.Create(s3, s2), funcLaji);//---------狀態選擇器---------    var rval = new Random();   Func<int,int> round = x => rval.Next(x);   s1.Selector = st => round(2)==0? s2:s3;   s2.Selector = st => round(2)==0? s1:s3;

構造完畢后,就可以使用這個狀態機了。

//選擇器跳轉   mess += "選擇器跳轉:/n------------------------/n";foreach (var stor in cont)    mess+=$"狀態轉變次數:{stor}/n";//直接控制跳轉mess += "/n直接控制狀態跳轉:/n------------------------/n";cont.transition(s1);cont.transition(s2);cont.transition(s3);

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VEVB武林網!


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久免费观看视频| 亚洲男人天堂2024| 欧美激情精品久久久久久黑人| 欧美日韩国产影院| 国产精品va在线播放| 国产成人激情小视频| 韩国19禁主播vip福利视频| 欧美一级bbbbb性bbbb喷潮片| 亚洲偷熟乱区亚洲香蕉av| 国产99久久精品一区二区永久免费| 综合136福利视频在线| 国内伊人久久久久久网站视频| 大胆人体色综合| 欧美午夜视频一区二区| 日本高清+成人网在线观看| 精品国产乱码久久久久久虫虫漫画| 97超碰国产精品女人人人爽| 久久大大胆人体| 久久精品小视频| 欧美尤物巨大精品爽| 亚洲激情免费观看| 日韩av在线免费观看一区| 色av吧综合网| 亚洲在线免费视频| 高清欧美一区二区三区| 2019中文字幕在线| 亚洲免费视频在线观看| 国产精品亚洲激情| 亚洲成色777777在线观看影院| 日韩精品视频免费专区在线播放| 亚洲人成在线免费观看| 中文字幕亚洲欧美一区二区三区| 亚洲香蕉成人av网站在线观看| 日韩一区在线视频| 欧美一级在线亚洲天堂| 91久久久久久国产精品| 欧美精品在线播放| 国产精品69久久| 欧美性xxxxx极品娇小| 高清日韩电视剧大全免费播放在线观看| 91网站免费观看| 成人在线观看视频网站| 在线观看日韩欧美| 欧美性受xxx| 国内揄拍国内精品少妇国语| 亚洲人成网站色ww在线| 亚洲新中文字幕| 久久福利网址导航| 久久久精品国产一区二区| 国产又爽又黄的激情精品视频| 亚洲成人精品久久| 91精品视频免费观看| 91精品国产综合久久久久久久久| 91国产精品电影| 91精品久久久久久久久久久久久| 91免费观看网站| 亚洲精品欧美日韩| 亚洲国产成人精品久久久国产成人一区| 亚洲国产成人精品电影| 国产97在线|亚洲| 久久久天堂国产精品女人| 亚洲一区二区三区四区视频| 日韩欧美精品网址| 久久精品视频在线观看| 亚洲成人免费在线视频| 琪琪第一精品导航| 在线电影av不卡网址| 亚洲女人天堂色在线7777| 亚洲国产高清自拍| 在线观看国产精品91| 97香蕉超级碰碰久久免费的优势| 国产免费一区视频观看免费| 亚洲免费视频一区二区| 在线观看精品自拍私拍| 一区二区成人精品| 91精品久久久久久久久久久久久久| 亚洲 日韩 国产第一| 欧美午夜美女看片| 国产精品久久久久999| 国产欧美精品日韩| 成人免费看吃奶视频网站| 中文字幕亚洲综合久久| 亚洲精品久久在线| 久久精品国产2020观看福利| 国产精品99久久久久久www| 九九视频这里只有精品| yw.139尤物在线精品视频| 欧美日本亚洲视频| 清纯唯美日韩制服另类| 国产精品免费久久久久影院| 日韩激情视频在线| 日韩美女视频免费看| 亚洲一级黄色片| 久久99久久99精品中文字幕| 色av中文字幕一区| 91亚洲国产成人久久精品网站| 日韩女优在线播放| 国产91热爆ts人妖在线| 国产精品久久久久久超碰| 成人xvideos免费视频| 自拍视频国产精品| 亚洲成人在线视频播放| 精品久久久av| 国产精品久久久久久久久免费| 久久久久久噜噜噜久久久精品| 久久久久久免费精品| 日韩精品免费在线播放| 亚洲无av在线中文字幕| 日本久久久久久| 亚洲女成人图区| 日韩精品视频中文在线观看| 中文字幕日韩专区| 中文字幕在线看视频国产欧美在线看完整| 成人黄色影片在线| 69影院欧美专区视频| 日韩中文字幕视频| 最近中文字幕mv在线一区二区三区四区| 国产91成人在在线播放| 久久男人av资源网站| 欧美成人三级视频网站| 国产狼人综合免费视频| 精品国产一区二区三区久久久狼| 成人在线国产精品| 亚洲sss综合天堂久久| 亚洲欧洲在线免费| 在线中文字幕日韩| 日本成人免费在线| 97在线视频精品| 国产欧美在线播放| 久久精品人人做人人爽| 国产精品wwww| 国产精品久久久久999| 精品欧美aⅴ在线网站| 欧美日韩免费一区| 日韩精品中文在线观看| 2019最新中文字幕| 亚洲自拍中文字幕| 97视频免费看| 欧美重口另类videos人妖| 久久99精品久久久久久噜噜| 成人精品久久一区二区三区| 欧美亚洲国产精品| 亚洲第一二三四五区| 亚洲老板91色精品久久| 欧美一级在线播放| 国产精品露脸自拍| 精品国产一区二区三区四区在线观看| 91啪国产在线| 欧洲成人在线观看| 黑人巨大精品欧美一区二区| 992tv在线成人免费观看| 日韩成人免费视频| 第一福利永久视频精品| 日本免费一区二区三区视频观看| 久久久久久久一| 亚洲国产精品人久久电影| 欧美猛男性生活免费| 92版电视剧仙鹤神针在线观看| 亚洲三级黄色在线观看| 久久99热精品这里久久精品| 亚洲最大的网站| 日韩av中文字幕在线播放| 日韩欧美亚洲成人| 亚洲美女性生活视频|