HTML5技术

C#用链式方法表达循环嵌套 - BillySir(3)

字号+ 作者:H5之家 来源:博客园 2016-06-03 11:00 我要评论( )

ComputeLinkT where T : ISeat3 3 { ComputeLinkT Child { T Obj { ComputeLink(T obj, ComputeLinkT parent, ActionT method) 8 { 9 if (obj == null ) ArgumentNullException( ); 11 this .Obj = obj; 12 this .O

ComputeLink<T> where T : ISeat3 3 { ComputeLink<T> Child { T Obj { ComputeLink(T obj, ComputeLink<T> parent, Action<T> method) 8 { 9 if (obj == null) ArgumentNullException(); 11 this.Obj = obj; 12 this.Obj.Method = x => method((T)x); 13 if (parent != null) 14 { 15 this.Parent = parent; 16 parent.Child = this; 17 parent.Obj.Child = this.Obj; 18 } 19 } ComputeLink<T> New(T obj, Action<T> method) 21 { ComputeLink<T>(obj, null, method); 23 } ComputeLink<T> Do(T obj, Action<T> method) 26 { ComputeLink<T>(obj, this, method); 28 } { { 33 if (null != this.Parent) .Parent.Head; ; 36 } 37 } Action() { 40 var head = this.Head; 41 head.Obj.Method(head.Obj); 42 } 43 } 44 interface ISeat3 45 { 46 ISeat3 Child { get; set; } 47 Action<ISeat3> Method { get; set; } 48 }

p.s.为什么第4版是ISeat3而不是ISeat4呢,因为我本不把第1版当作1个版本,因为太原始了,出现第2版后,我就把第1版给删除了。为了写这篇文章才重新去写第1版。于是原本我当作第3版的ISeat3自然地排到了第4版。

具体的"算法"就很简单了:

class Seat3 : ISeat3 { static Seat data = new Seat(); string Name { get; set; } public Seat3(string name) { this.Name = name; } 解耦的版本 Run() { var sql = ComputeLink<Seat3> .New(), m => m.Try()) .Do(), m => m.Try()) .Do(), m => m.Try()) .Do(), m => m.Try()) .Do(), m => m.Try2()) .Do(), m => m.Try2()) .Do(), m => m.Try2()) .Do(), m => m.Try2()) .Do(new Seat3(""), m => m.Print()); sql.Action(); } public Action<ISeat3> Method { get; set; } public ISeat3 Child { get; set; } public void Try() { for (int i = 0; i < 4; i++) { if (data.IsSelected(0, i)) continue; data.Selected(0, i, this.Name); if (this.Child != null) { this.Child.Method(this.Child); } data.UnSelected(0, i); } } public void Try2() { for (int i = 0; i < 5; i++) { if (i == 1) continue; if (data.IsSelected(1, i)) continue; if (data.IsSelected(0, i, this.Name)) continue; data.Selected(1, i, this.Name); if (this.Child != null) { this.Child.Method(this.Child); } data.UnSelected(1, i); } } public void Print() { data.Count++; Console.WriteLine(, data.Count, data.Current); } }

Seat3写起来简单,(Run方法内部)看起来舒服。通过链式写法达到嵌套循环的效果。对,这就是我要的!
它很像linq,所以我直接给变量命名为sql。

  • 对于Try和Try2来讲,要调用的方法最好从参数传来,但是这样就会增加Run方法中New和Do的参数复杂性,破坏了美感,所以经过权衡,Child和Method通过属性传入。这个我也不确定这样做好不好,请各位大侠指点。
  • 还有一个细节,就是ComputeLink构造方法中的(行号12的)代码 this.Obj.Method = x => method((T)x); 。我原来是这样写的 this.Obj.Method = method; 编译不通过,原因是不能把 Action<ISeat3> 转化为 Action<T> ,虽然T一定实现了ISeat3,强制转化也不行,想起以前看过的一篇文章里面提到希望C#以后的版本能拥有的一特性叫“协变”,很可能指的就是这个。既然这个 Action<ISeat3> 不能转化为 Action<T> 但是ISeat3是可以强制转化为T的,所以我包了一层薄薄的壳,成了 this.Obj.Method = x => method((T)x); ,如果有更好的办法请告诉我。
  •  

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • Java 8 Lambda 表达式 - Felix_ICanFixIt

      Java 8 Lambda 表达式 - Felix_ICanFixIt

      2017-04-22 17:04

    • C# 快速高效率复制对象另一种方式 表达式树 - Emrys5

      C# 快速高效率复制对象另一种方式 表达式树 - Emrys5

      2017-04-06 14:00

    • Omi v1.0.2发布 - 正式支持传递javascript表达式 - 【当耐特】

      Omi v1.0.2发布 - 正式支持传递javascript表达式 - 【当耐特】

      2017-03-22 11:03

    • 关于ionic2打包android时gradle下载不了的解决方法(附:简单优化启动速度彩蛋) - 无所事事者爱嘲笑

      关于ionic2打包android时gradle下载不了的解决方法(附:简单优化启

      2017-03-03 13:00

    网友点评