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

这篇具有很好参考价值的文章主要介绍了链式-父类中返回子类对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

但是由于链式调用父类的接口返回父类对象,就无法继续链式了。说明可能不清楚,直接show 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     }

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


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 (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<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

 文章来源地址https://www.toymoban.com/news/detail-449348.html

到了这里,关于链式-父类中返回子类对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ | 继承(基类,父类,超类),(派生类,子类)

    文章参考:https://blog.csdn.net/war1111886/article/details/8609957 一 .继承中的访问权限关系 1.基类,父类,超类是指被继承的类,派生类,子类是指继承于基类的类.  2.在C++中使用: 冒号表示继承,如class A : public B;表示派生类A从基类B继承而来 3.派生类包含基类的所有

    2024年02月15日
    浏览(42)
  • c++和QT子类调用父类方法

    c++调用方式 : 父类名::方法名 QT调用方式 : __super::方法

    2024年02月13日
    浏览(48)
  • C# 中什么是重写(子类改写父类方法)

    方法重写是指在继承关系中,子类重新实现父类或基类的某个方法。这种方法允许子类根据需要修改或扩展父类或基类的方法功能。在面向对象编程中,方法重写是一种多态的表现形式,它使得子类可以根据不同的需求和场景提供不同的方法实现。 方法重写的基本规则如下:

    2024年02月09日
    浏览(49)
  • Java父类强制转换为子类的三种情况(推荐)

    Father f = new Father(); Son s = (Son)f;//出错 ClassCastException Father f = new Son(); Son s = (Son)f;//可以 f只能用父类的方法 s可以用子类的所有方法 Son s = new Son(); Father f = (Father)s;//可以 f只能用父类的方法

    2024年02月08日
    浏览(40)
  • java子类继承父类方法、或者接口中方法的javadoc注释

    详情可以阅读: https://docs.oracle.com/en/java/javase/19/docs/specs/javadoc/doc-comment-spec.html#method-comment-inheritance 子类继承父类、或者子类实现接口,在子类中为了避免重复写注释,可以在子类方法注释的主要描述部分、或者@return、@param、@throws标记后面的文本参数部分插入{@inheritDoc}标记

    2024年02月11日
    浏览(43)
  • 【C++】 为什么多继承子类重写的父类的虚函数地址不同?『 多态调用汇编剖析』

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 本篇文章主要是为了解答有关多态的那篇文章那块的一个奇怪现象,大家还记得这张

    2024年02月19日
    浏览(38)
  • C# 父类实现的 IEquatable<T> 接口,重写的相等性判断函数都能被子类继承

    在父类重写的 Equals 方法,继承的 IEquatable 接口,重写的 == ,!= 运算符,重写的 GetHashCode 方法在子类中仍然是表现为被重写的状态。 现在让子类也实现 IEquatable 接口 此时代码提示如下 子类实现接口后,调用的默认就是子类实现的 Equals 方法。也可以用强制转换调用父类的

    2024年02月16日
    浏览(43)
  • C# 子类强制转换为父类异常,引出的C#Dll加载机制,以及同类名同命名空间同dll程序集在C#中是否为同一个类的研究。

    已知,子类B继承自父类A,但是在代码运行时,B类强制转换为A类,却报代码转换异常。 很奇怪的问题吧,不过这个也是难得机会,去研究C#运行的底层原理。 下面是报错的代码片段。 下面是报错结果(其中的敏感字符串被替换成了xxx): 通过上面的代码可以看出,从子类中

    2024年02月13日
    浏览(43)
  • Spring MVC学习之——Controller类中方法的返回值

    2.1逻辑视图名 说明:controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。 返回字符串 2.2Redirect重定向 说明: Contrller方法返回结果重定向到一个url地址,如下商品修改提交后重定向到商品查询方法,参数无法带到商品查询方法中。 redirect方式

    2024年01月18日
    浏览(65)
  • C++之模板类指向子类对象(一百四十六)

    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏: Audio工程师进阶系列 【 原创干货持续更新中…… 】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:An

    2024年02月12日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包