让“链式调用(方法链)”更加自然一点

不论是JavaScript还是C#程序,我们已经习惯了采用如下所示的“链式调用”的方式进行编程,这样确实会使我们的程序变得很精练。

   1: new Foo()
   2:     .UseXxx()
   3:     .UseZzz()
   4:     .UseZzz()
   5:     .Invoke();

采用这种链式调用方式的很多方法都是扩展方法,比如上面所示的UseXxx、UseYyy和UseXxx方法就是采用如下形式定义的扩展方法。

   1: public interface IFoo
   2: {
   3:     void Invoke();
   4: }
   5:  
   6: public class Foo : IFoo
   7: {
   8:     public void Invoke()
   9:     {}
  10:     public void Execute()
  11:     {}
  12: }
  13:  
  14: public static class FooExtensions
  15: {
  16:     public static IFoo UseXxx(this IFoo foo)
  17:     {
  18:         return foo;
  19:     }
  20:     public static IFoo UseYyy(this IFoo foo)
  21:     {
  22:         return foo;
  23:     }
  24:     public static IFoo UseZzz(this IFoo foo)
  25:     {
  26:         return foo;
  27:     }
  28: }

到目前为止,一切都显得很完美,而且我看到绝大部分的扩展方法也是采用这种方式定义的。但是如果我们希望采用如下的方式调用Foo的Execute方法的,很明显下面这样的代码是不能通过编译的。

   1: new Foo()
   2:     .UseXxx()
   3:     .UseZzz()
   4:     .UseZzz()
   5:     .Execute();

我们不得不将这段代码改写成如下的形式。改写的代码显得很丑陋,和上面这段代码相比较:第一、多声明了一个变量;第二、将一段很“流畅”的代码活生生拆分成两段;第三、在调用Execute方法是添加了一个很“生硬”的类型转换。

   1: IFoo foo = new Foo()
   2:     .UseXxx()
   3:     .UseYyy()
   4:     .UseZzz();
   5:  
   6: ((Foo)foo).Execute();

如果希望上面这段代码合法有效,我们的三个扩展方法应该定一个成如下的形式。

   1: public static class FooExtensions
   2: {
   3:     public static T UseXxx<T>(this T foo) where T: IFoo
   4:     {
   5:         return foo;
   6:     }
   7:     public static T UseYyy<T>(this T foo) where T : IFoo
   8:     {
   9:         return foo;
  10:     }
  11:     public static T UseZzz<T>(this T foo) where T : IFoo
  12:     {
  13:         return foo;
  14:     }
  15: }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏喵了个咪的博客空间

zephir-(12)php函数和异常处理

#zephir-php函数和异常处理# ? ##前言## 先在这里感谢各位zephir开源技术提供者 经过了一个多月的学习,zephir的文档译文和基础讲解也将...

3566
来自专栏xingoo, 一个梦想做发明家的程序员

MFC中注释含义

下面是 CStdioFile 类的部分列表,其中使用了 MFC 在其类中按类成员的用法划分它们时所采用的大多数标准注释: class CStdioFile :...

1947
来自专栏WeaponZhi

AI 学习之路——轻松初探 Python 篇(二)

这是「AI 学习之路」的第 2 篇,「Python 学习」的第 2 篇 我将分两篇讲解下 Python 的基础语法,这是第一篇。大家也可以在很多地方看到入门的学...

39512
来自专栏学习力

《Java从入门到放弃》框架入门篇:Struts2的基本数据传递方式 推荐

1664
来自专栏ACM算法日常

UVA10305 | 拓扑排序

John has n tasks to do. Unfortunately, the tasks are not independent and the exe...

772
来自专栏Java帮帮-微信公众号-技术文章全总结

Java 8 Lambda函数编程【面试+工作】

链接:https://pan.baidu.com/s/1q_S2URG8mWKI1nTvPVvDzg 密码:2als

2033
来自专栏java学习

Java每日一练(2017/6/4)

题目要求 删除目录功能: 客户任意输入一个路径,若路径格式正确则输出该路径下的所有文件夹名称 并提示“是否要删除以下的文件夹(注意:文件夹下面的所有内容...

2985
来自专栏撸码那些事

【封装那些事】 泄露的封装

1362
来自专栏恰同学骚年

数据结构基础温故-6.查找(下):哈希表

哈希(散列)技术既是一种存储方法,也是一种查找方法。然而它与线性表、树、图等结构不同的是,前面几种结构,数据元素之间都存在某种逻辑关系,可以用连线图示表示出来,...

1351
来自专栏web前端教室

js不好学并不是因为它难,而是因为它容易混淆

这段时间我主讲的前端零基础课,让我感觉js这东西是越来越简单了。你当然可以说我这是越讲课越熟。确实是有这部分因素,但更主要的是,我发现js中虽然有许多的概念各不...

2477

扫码关注云+社区

领取腾讯云代金券