链式-父类返回之类对象

科技资讯 投稿 6400 0 评论

链式-父类返回之类对象

对于自己写着完的代码,我特别喜欢链式(来源于jQuery的影响吧),大部分时候链式就是将返回值为void类型的对象,返回this指针,直到我遇到一个特殊情况——在父类中返回子类类型。大部分情况父类都不知道子类有什么,根本没有返回子类的需求


 1  public class OldWhereV2<T>
 2     {
 3         protected Expression<Func<T, bool>> expression = null;
 4 
 5         public OldWhereV2<T> Where(Expression<Func<T, bool>> memberExpression
 6         {
 7             return this;
 8         }
 9 
10         public OldWhereV2<T> Or(Expression<Func<T, bool>> memberExpression
11         {
12             return this;
13         }
14 
15         public OldWhereV2<T> Add(Expression<Func<T, bool>> memberExpression
16         {
17             return this;
18         }
19     }
20 
21     public class OldQeuryV2<T> : OldWhereV2<T>
22     {
23 
24         public OldQeuryV2<T> Select(Expression<Func<T, object>> memberExpression
25         {
26             return this;
27         }
28 
29         public OldQeuryV2<T> Take(int count
30         {
31             return this;
32         }
33 
34         public OldQeuryV2<T> Order(Expression<Func<T, object>> memberExpression, bool asc
35         {
36             return this;
37         }
38     }

调用的时候,如果使用链式

1  var query =new OldQeuryV2<Train>(
2                .Select(x => x.Apply_Time
3                .Select(x => x.Apply_Time
4                .Select(x => x.Approval_OrgName
5                .Where(x => x.Create_Time > DateTime.Now
6                .Add(x => x.Approval_OrgName == ""
7                .Order(x => x.Approval_OrgGID, true
8                .Order(x => x.Apply_Time, false
9                .Take(10;

 .Order(x => x.Approval_OrgGID, true 这行代码会报错的。因为Where返回的是OldWhereV2<T>类型,而Order方法要求OldQeuryV2<T>类型

 1  public abstract class Condition<T, M> where M : Condition<T, M>
 2     {
 3         protected Expression<Func<T, bool>> expression = null;
 4 
 5         public M Where(Expression<Func<T, bool>> memberExpression
 6         {
 7             expression = memberExpression;
 8             return (Mthis;
 9         }
10 
11         public M Or(Expression<Func<T, bool>> memberExpression
12         {
13             if (expression == null
14             {
15                 expression = memberExpression;
16             }
17             else
18             {
19                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast<Expression>(;
20                 expression = Expression.Lambda<Func<T, bool>>(Expression.OrElse(expression.Body, invokedExpr, expression.Parameters;
21             }
22             return (Mthis;
23         }
24 
25         public M Add(Expression<Func<T, bool>> memberExpression
26         {
27             if (expression == null
28             {
29                 expression = memberExpression;
30             }
31             else
32             {
33                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast<Expression>(;
34                 expression = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expression.Body, invokedExpr, expression.Parameters;
35             }
36             return (Mthis;
37         }
38     }
39 
40     public class Qeury<T> : Condition<T, Qeury<T>>
41     {
42         List<MemberInfo> selects = new List<MemberInfo>(;
43         Dictionary<MemberInfo, bool> orders = new Dictionary<MemberInfo, bool>(;
44         int count = 1000;
45 
46         public Qeury<T> Select(Expression<Func<T, object>> memberExpression
47         {
48             MemberInfo memberInfo = memberExpression.GetMemberInfo(;
49             if (!selects.Contains(memberInfo
50             {
51                 selects.Add(memberInfo;
52             }
53             return this;
54         }
55 
56         public Qeury<T> Take(int count
57         {
58             this.count = count;
59             return this;
60         }
61 
62         public Qeury<T> Order(Expression<Func<T, object>> memberExpression, bool asc
63         {
64             MemberInfo memberInfo = memberExpression.GetMemberInfo(;
65             if (orders.ContainsKey(memberInfo
66             {
67                 orders[memberInfo] = asc;
68             }
69             else
70             {
71                 orders.Add(memberInfo, asc;
72             }
73             return this;
74         }
75 
76         public string QeurySql(
77         {
78             var queryInfo = new QueryInfo(
79             {
80                 WhereExpression = this.expression,
81                 SelectFields = this.selects,
82                 Orders = this.orders,
83                 Count = this.count
84             };
85 
86             return TableAnalysis.GetTableInfo(typeof(T.QeurySql(queryInfo;
87         }
88     }

这里将Condition<T>类修改为Condition<T,M> 而M是Condition<T,M>的子类,返回的时候只需要返回M类型就好了,当然由于Condition返回了子类,所以我把它设置成了抽象类,但是也可以不用。由于Qeury<T> :实现了Condition<T, Qeury<T>>,所以子类就可以正常调用父类的方法了。

1 var query =new Qeury<Train>(
2                .Select(x => x.Apply_Time
3                .Select(x => x.Apply_Time
4                .Select(x => x.Approval_OrgName
5                .Where(x => x.Create_Time > DateTime.Now
6                .Add(x => x.Approval_OrgName == ""
7                .Order(x => x.Approval_OrgGID, true
8                .Order(x => x.Apply_Time, false
9                .Take(10;

这个算是奇技淫巧,发出来给大家看看,不过不链式不久没有烦恼了吗,正常如下面定义就好了

1 public class OldCondition<T> 2 { 3 public void Where(Expression<Func<T, bool>> memberExpression 4 { 5 6 } 7 8 public void Or(Expression<Func<T, bool>> memberExpression 9 { 10 11 } 12 13 public void Add(Expression<Func<T, bool>> memberExpression 14 { 15 16 } 17 } 18 19 public class OldQeury<T> : OldCondition<T> 20 { 21 public void Select(Expression<Func<T, object>> memberExpression 22 { 23 24 } 25 26 public void Take(int count 27 { 28 29 } 30 31 public void Order(Expression<Func<T, object>> memberExpression, bool asc 32 { 33 34 } 35 }

View Code

 

编程笔记 » 链式-父类返回之类对象

赞同 (35) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽