【资料图】
一晃五年没写博客了,依旧再C#上耕耘,依旧没有啥建树,现在也不知道.net上还有多少人再使用,在这里分享一些自己觉得写的还算优雅的代码。
对于自己写着完的代码,我特别喜欢链式(来源于jQuery的影响吧),大部分时候链式就是将返回值为void类型的对象,返回this指针,直到我遇到一个特殊情况——在父类中返回子类类型。大部分情况父类都不知道子类有什么,根本没有返回子类的需求
但是由于链式调用父类的接口返回父类对象,就无法继续链式了。说明可能不清楚,直接show code
1 public class OldWhereV22 { 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 : OldWhereV2 22 {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
这个问题困扰我一晚,后来我记得在哪里看过一本书,书中有泛型自包含的例子,但是当时完全看不懂,但是此处感觉使用完全没毛病所以就做了简单修改
1 public abstract class Conditionwhere 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
具体例子如下:
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 OldConditionView Code2 { 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 : OldCondition 20 {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 }