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

首頁 > 編程 > C# > 正文

一個狀態機的實現

2020-01-24 00:47:29
字體:
來源:轉載
供稿:網友

話不多說,先看代碼:

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);

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美亚洲激情在线| 欧美在线影院在线视频| 精品国产老师黑色丝袜高跟鞋| 欧美极品xxxx| 欧美丰满少妇xxxx| 亚洲已满18点击进入在线看片| 国产精品欧美一区二区三区奶水| 亚洲国产精品网站| 777国产偷窥盗摄精品视频| 日韩亚洲国产中文字幕| 国产丝袜一区二区| 91手机视频在线观看| 亚洲激情电影中文字幕| 欧美高跟鞋交xxxxxhd| 亚洲午夜av久久乱码| 国产成人精品亚洲精品| 91sao在线观看国产| 欧美小视频在线| 国产精品视频地址| 91亚洲一区精品| 亚洲国产欧美日韩精品| 亚洲精品久久久一区二区三区| 色爱精品视频一区| 久久久久这里只有精品| 97热精品视频官网| 欧美亚洲视频一区二区| 国产精品日日摸夜夜添夜夜av| 精品久久久久久久久中文字幕| 日韩av理论片| 奇米4444一区二区三区| 日韩免费观看av| 一本色道久久88综合日韩精品| 欧美日韩一区二区免费视频| 久久久久999| 日韩动漫免费观看电视剧高清| 国产成人+综合亚洲+天堂| 日韩中文在线视频| 午夜伦理精品一区| 在线播放国产一区二区三区| 亚洲免费视频在线观看| 欧美成人三级视频网站| 国产精品视频公开费视频| 色综合久综合久久综合久鬼88| 久久成人精品一区二区三区| 日韩国产激情在线| 欧美性高潮在线| 亚洲成人激情小说| 国产精品夜色7777狼人| 在线观看成人黄色| 久久久免费高清电视剧观看| 日韩精品视频在线免费观看| www亚洲精品| 国产在线拍偷自揄拍精品| 欧美有码在线观看| 中文字幕少妇一区二区三区| 亚洲欧美国产制服动漫| 成人有码在线视频| 68精品国产免费久久久久久婷婷| 国产精品黄色影片导航在线观看| 亚洲色图17p| 色香阁99久久精品久久久| 久久6免费高清热精品| 亚洲精品日产aⅴ| 亚洲成av人片在线观看香蕉| 久久精品在线播放| 久久成人av网站| 亚洲人成在线免费观看| 国产一区二区三区四区福利| 日韩国产欧美精品在线| 亚洲欧美成人一区二区在线电影| 美女国内精品自产拍在线播放| 最近中文字幕日韩精品| 黄网动漫久久久| 久久久www成人免费精品| 欧美在线一级视频| 欧美高清在线播放| 欧美日韩加勒比精品一区| 91高清视频在线免费观看| 成人黄色午夜影院| 在线一区二区日韩| 黑人巨大精品欧美一区免费视频| 欧美高清视频在线| 色婷婷久久av| 国产精品一区二区三区在线播放| 亚洲国产高清自拍| 亚洲伊人久久综合| 欧美专区中文字幕| 久久九九亚洲综合| 亚洲乱亚洲乱妇无码| 久久久久这里只有精品| 久久精品久久久久久国产 免费| 91精品视频免费观看| 国产免费成人av| 国产精品日日摸夜夜添夜夜av| 亚洲摸下面视频| 精品亚洲一区二区三区在线播放| 精品福利视频导航| 久久久中精品2020中文| 国内精品中文字幕| 欧美精品九九久久| 综合欧美国产视频二区| 亚洲综合小说区| 欧美成人免费在线观看| 精品国产精品三级精品av网址| 久久久久国产视频| 人妖精品videosex性欧美| 欧美大码xxxx| 日韩中文字幕在线观看| 欧美福利在线观看| 91免费国产网站| 国产免费一区视频观看免费| 欧美大尺度电影在线观看| 日韩欧美在线免费| 国产精品欧美激情| 欧美日韩国产中文字幕| 欧美亚洲一区在线| 欧美精品久久久久久久久久| 国产精品三级在线| 亚洲女成人图区| 欧美激情精品久久久久久| 另类专区欧美制服同性| 亚洲男子天堂网| 久久91亚洲精品中文字幕奶水| 欧美一性一乱一交一视频| 中文字幕一区电影| 亚洲国产欧美精品| 欧美日韩一区二区在线| 日韩电影免费观看在线观看| 91久久精品在线| 国产在线98福利播放视频| 91视频国产精品| 国产精品 欧美在线| 成人精品久久一区二区三区| 欧美成人免费全部观看天天性色| 国产精品嫩草视频| 亚洲影院在线看| 国产综合香蕉五月婷在线| 欧美在线视频观看免费网站| 精品久久久久久久久久ntr影视| 欧美巨猛xxxx猛交黑人97人| 欧美视频专区一二在线观看| 色偷偷偷综合中文字幕;dd| 日韩免费黄色av| 国产精品电影观看| 亚洲a在线播放| 亚洲精品国产拍免费91在线| 欧美成人午夜免费视在线看片| 大胆欧美人体视频| 亚洲欧美中文日韩在线v日本| 97免费在线视频| 另类专区欧美制服同性| 久久精品福利视频| 中文字幕日韩免费视频| 国产丝袜精品视频| 日本成人免费在线| 自拍偷拍亚洲精品| 91在线免费看网站| 久久成人一区二区| 国产精品无av码在线观看| 精品毛片三在线观看| 欧美视频免费在线| 亚洲午夜久久久影院| 在线视频欧美日韩| 国产成人免费av|