当前位置: 首页 > 聚焦 > > 内容页

天天看点:链式-父类中返回子类对象

来源:博客园 时间: 2023-05-18 18:15:28


【资料图】

一晃五年没写博客了,依旧再C#上耕耘,依旧没有啥建树,现在也不知道.net上还有多少人再使用,在这里分享一些自己觉得写的还算优雅的代码。

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

但是由于链式调用父类的接口返回父类对象,就无法继续链式了。说明可能不清楚,直接show code

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

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

1  var query =new OldQeuryV2()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类型,而Order方法要求OldQeuryV2类型

这个问题困扰我一晚,后来我记得在哪里看过一本书,书中有泛型自包含的例子,但是当时完全看不懂,但是此处感觉使用完全没毛病所以就做了简单修改

1  public abstract class Condition where M : Condition 2     { 3         protected Expression> expression = null; 4  5         public M Where(Expression> memberExpression) 6         { 7             expression = memberExpression; 8             return (M)this; 9         }10 11         public M Or(Expression> memberExpression)12         {13             if (expression == null)14             {15                 expression = memberExpression;16             }17             else18             {19                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast());20                 expression = Expression.Lambda>(Expression.OrElse(expression.Body, invokedExpr), expression.Parameters);21             }22             return (M)this;23         }24 25         public M Add(Expression> memberExpression)26         {27             if (expression == null)28             {29                 expression = memberExpression;30             }31             else32             {33                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast());34                 expression = Expression.Lambda>(Expression.AndAlso(expression.Body, invokedExpr), expression.Parameters);35             }36             return (M)this;37         }38     }39 40     public class Qeury : Condition>41     {42         List selects = new List();43         Dictionary orders = new Dictionary();44         int count = 1000;45 46         public Qeury Select(Expression> 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 Take(int count)57         {58             this.count = count;59             return this;60         }61 62         public Qeury Order(Expression> memberExpression, bool asc)63         {64             MemberInfo memberInfo = memberExpression.GetMemberInfo();65             if (orders.ContainsKey(memberInfo))66             {67                 orders[memberInfo] = asc;68             }69             else70             {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.count84             };85 86             return TableAnalysis.GetTableInfo(typeof(T)).QeurySql(queryInfo);87         }88     }

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

具体例子如下:

1 var query =new Qeury()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 2     { 3         public void Where(Expression> memberExpression) 4         { 5  6         } 7  8         public void Or(Expression> memberExpression) 9         {10 11         }12 13         public void Add(Expression> memberExpression)14         {15 16         }17     }18 19     public class OldQeury : OldCondition20     {21         public void Select(Expression> memberExpression)22         {23 24         }25 26         public void Take(int count)27         {28 29         }30 31         public void Order(Expression> memberExpression, bool asc)32         {33 34         }35     }
View Code
上一篇:林州市属于哪个市管辖_林州市属于哪个市 世界速讯 下一篇:最后一页
x

推荐阅读