• 链式-父类中返回子类对象


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

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

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

    复制代码
    
    
    复制代码
     1  public class OldWhereV2
     2     {
     3         protected Expressionbool>> expression = null;
     4 
     5         public OldWhereV2 Where(Expressionbool>> memberExpression)
     6         {
     7             return this;
     8         }
     9 
    10         public OldWhereV2 Or(Expressionbool>> memberExpression)
    11         {
    12             return this;
    13         }
    14 
    15         public OldWhereV2 Add(Expressionbool>> memberExpression)
    16         {
    17             return this;
    18         }
    19     }
    20 
    21     public class OldQeuryV2 : OldWhereV2
    22     {
    23 
    24         public OldQeuryV2 Select(Expressionobject>> memberExpression)
    25         {
    26             return this;
    27         }
    28 
    29         public OldQeuryV2 Take(int count)
    30         {
    31             return this;
    32         }
    33 
    34         public OldQeuryV2 Order(Expressionobject>> 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 Expressionbool>> expression = null;
     4 
     5         public M Where(Expressionbool>> memberExpression)
     6         {
     7             expression = memberExpression;
     8             return (M)this;
     9         }
    10 
    11         public M Or(Expressionbool>> memberExpression)
    12         {
    13             if (expression == null)
    14             {
    15                 expression = memberExpression;
    16             }
    17             else
    18             {
    19                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast());
    20                 expression = Expression.Lambdabool>>(Expression.OrElse(expression.Body, invokedExpr), expression.Parameters);
    21             }
    22             return (M)this;
    23         }
    24 
    25         public M Add(Expressionbool>> memberExpression)
    26         {
    27             if (expression == null)
    28             {
    29                 expression = memberExpression;
    30             }
    31             else
    32             {
    33                 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast());
    34                 expression = Expression.Lambdabool>>(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         Dictionarybool> orders = new Dictionarybool>();
    44         int count = 1000;
    45 
    46         public Qeury Select(Expressionobject>> 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(Expressionobject>> 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()
    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(Expressionbool>> memberExpression)
     4         {
     5 
     6         }
     7 
     8         public void Or(Expressionbool>> memberExpression)
     9         {
    10 
    11         }
    12 
    13         public void Add(Expressionbool>> memberExpression)
    14         {
    15 
    16         }
    17     }
    18 
    19     public class OldQeury : OldCondition
    20     {
    21         public void Select(Expressionobject>> memberExpression)
    22         {
    23 
    24         }
    25 
    26         public void Take(int count)
    27         {
    28 
    29         }
    30 
    31         public void Order(Expressionobject>> memberExpression, bool asc)
    32         {
    33 
    34         }
    35     }
    View Code

     

  • 相关阅读:
    jupyter notebook使用相对路径的方法
    Xshell在Windows和Linux间文件的上传和下载
    J2EE基础-通用分页
    基于Java毕业设计中国古诗词学习平台源码+系统+mysql+lw文档+部署软件
    Matlab论文插图绘制模板第122期—函数折线图(fplot)
    飞书前端提到的竞态问题,在 Android 上怎么解决?
    数据库配置mysql5.7
    回归 Regression
    Spring Data JDBC & Spring Data JPA
    虚拟内存相关笔记
  • 原文地址:https://www.cnblogs.com/watermoon2/p/17412967.html