|
一晃五年没写博客了,依旧再C#上耕耘,依旧没有啥建树,现在也不知道.net上还有多少人再使用,在这里分享一些自己觉得写的还算优雅的代码。
对于自己写着完的代码,我特别喜欢链式(来源于jQuery的影响吧),大部分时候链式就是将返回值为void类型的对象,返回this指针,直到我遇到一个特殊情况——在父类中返回子类类型。大部分情况父类都不知道子类有什么,根本没有返回子类的需求
但是由于链式调用父类的接口返回父类对象,就无法继续链式了。说明可能不清楚,直接show code- [/code][code] 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 }
复制代码 调用的时候,如果使用链式- [/code][code]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);
复制代码- [/code] .Order(x => x.Approval_OrgGID, true) 这行代码会报错的。因为Where返回的是OldWhereV2类型,而Order方法要求OldQeuryV2类型
- 这个问题困扰我一晚,后来我记得在哪里看过一本书,书中有泛型自包含的例子,但是当时完全看不懂,但是此处感觉使用完全没毛病所以就做了简单修改
- [code] 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 (M)this;
- 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 (M)this;
- 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 (M)this;
- 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类修改为Condition 而M是Condition的子类,返回的时候只需要返回M类型就好了,当然由于Condition返回了子类,所以我把它设置成了抽象类,但是也可以不用。由于Qeury :实现了Condition,所以子类就可以正常调用父类的方法了。
具体例子如下:- 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
来源:https://www.cnblogs.com/watermoon2/archive/2023/05/18/17412967.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|