博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在已经定义好的系统类或者自定义类中添加扩展方法
阅读量:5973 次
发布时间:2019-06-19

本文共 3868 字,大约阅读时间需要 12 分钟。

在开发时,有时会发现已定的类的方法并不能够全部满足需求,这时如果要扩展这个类,可以考虑通过继承新增一个类,那如如原来的类是密封类(sealed),那不就无法继承呢?这该怎么办呢?有人会说,这时可以再新建一个类,并将类名在原类上加一个加缀Extension。比如原类是Employee,这时可以叫做EmployeeExtension。这当然是可以的。

那还有没有什么办法可以在沿用原类名的基础上去扩展该类的方法呢?答案是有的!这就是要用到类的扩展。我们先来扩展一个系统类,比如DirectoryInfo。在使用DirectoryInfo时,可能会希望增加一个CopyTo的方法以实现将目录下的文件拷贝到另一个目录下,但原DriectoryInfo是没有的,看下图。

新建了一个DirectoryInfo的实例directory,然后展开相应的方法,在Attributes后就是Create,直到CreationTimeUtc的所有C开头的方法和属性中并没有一个CopyTo的方法。现在我们再看看通过扩展后的图。

我们可以看到,这时的directory这时多了CopyTo的方法,而且前面的图标多了一个表示扩展的向下箭头,同时右边的说明部分也标有“扩展”的字样。那这个是如何添加进去的呢?我们先来看扩展的代码

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;namespace Extensions{    ///     /// Extension DirectoryInfo.    ///     public static class DirectoryInfoExtension    {        ///         /// Copy source directory to target directory.        ///         ///         ///         ///         ///         public static void CopyTo(this DirectoryInfo sourceDirectory,                                    string target, SearchOption option, string searchParttern)        {            //TODO            Console.WriteLine("Copy to {0}", target);        }    }  }
首先,这里我们增加了一个静态类DirectoryInfoExtension(类名不限定,不过习惯上是在原类名上加Extension的后缀),注意一定要是静态方法。

其次,在这个静态类中添加了一个CopyTo的静态方法,注意一定要是静态方法。

再次,在CopyTo这个方法中,第一个参数是以this开始,同时以要扩展的类作为类型DirectoryInfo,并定义一个参数sourceDirectory(该参数在调用CopyTo方法时,并不作为传入参数)。

最后,在第一个参数之后定义target等几个参数是CopyTo方法被调用时实际使用的参数,然后方法体内的代码和普通的方法一样。

需要注意几点

1.这里虽然是以静态方法定义的,但是在使用时却是要以实例的形式来调用,即定义DirectoryInfo的实例directory,然后以directory.CopyTo调用。

2.在使用的地方,一定要记得添加扩展的命名字间引用,如上例中是在Extensions的命名空间下写的代码,所以在使用的地方需要增加using Extensions,不然扩展方法用不了。

那这样扩展之后,方法是否能正常执行呢?下面是测试代码和测试结果。

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;//Addusing Extensions;namespace ExtensionMethod{    class Program    {        static void Main(string[] args)        {            DirectoryInfoExtensionTest();                   Console.ReadLine();        }        private static void DirectoryInfoExtensionTest()        {            DirectoryInfo directory = new DirectoryInfo(@".");            directory.CopyTo(@"F:\Tagget",SearchOption.AllDirectories,"*");                    }    }}

我们可以看到,CopyTo方法正常执行了,这说明扩展成功了。

这是对于系统类进行扩展的。有时我们会遇到只有DLL或者EXE程序集的类库,如第三方类库,这时我们是否可以按同样的方法扩展呢?答案是可以的!下面是一个简单的Log的类库的代码。

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Log{    public sealed class Record    {        public void Write(string info)        {            Console.WriteLine(info);            Console.WriteLine("Write to local disk OK!");        }    }}
这里以控制台输出的形式表示日志记录在了磁盘上,而有时我们为了方便数据的查询,会希望日志是记录在数据库中,这时我们可以通过扩展方法的形式来扩展。下面是扩展方法的代码

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using Log;namespace Extensions{     ///     /// Extension Record    ///     public static class RecordExtension    {        public static void WriteDatabase(this Record record, string info)        {            Console.WriteLine(info);            Console.WriteLine("Write to database OK!");        }    }}
同样是定义了一个Record的静态扩展类RecordExtension,然后增加WriteDatabase的方法,后面的第一个参数是this开头,之后是要扩展的类Reocrd的类型,再之后的参数info才是真正的传递参数。下面是测试代码和测试结果。

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;//Addusing Extensions;using Log;namespace ExtensionMethod{    class Program    {        static void Main(string[] args)        {                      DefineClassExtensionTest();            Console.ReadLine();        }        private static void DefineClassExtensionTest()        {            Record record = new Record();            string info="This is my log record!";            record.Write(info);            record.WriteDatabase(info);        }        }}

通过扩展方法的运用,可以在不改变原类的情况下实现扩展。具体也可参照该文《》

转载于:https://www.cnblogs.com/sparkleDai/p/7605059.html

你可能感兴趣的文章
iOS开发UI篇—Quartz2D使用(图片剪切)
查看>>
spring学习笔记(20)数据库事务并发与锁详解
查看>>
关于Simple_html_dom的小应用
查看>>
鲁肃:蚂蚁金服的三个梦想
查看>>
【springmvc+mybatis项目实战】杰信商贸-27.POI由HSSF升级为XSSF
查看>>
数学常数e的含义
查看>>
Spring Boot MyBatis 通用Mapper插件集成
查看>>
Django跟Bootstrap3体验以及相比框架提问
查看>>
APM基础小记
查看>>
Omi 6.0 - Store 的设计哲学
查看>>
福利 | 20张2019年蓝牙大会通票免费领
查看>>
XSwitch - 一个解决本地开发请求转发的浏览器插件
查看>>
无限循环RecyclerView的完美实现方案
查看>>
Android中的消息机制
查看>>
TCP - 基础
查看>>
前端常用代码示例-1
查看>>
多线程安全-sychronized
查看>>
Amazing tree —— 二叉查找树
查看>>
2048块GPU再次加速SGD:富士通74.7秒完成ResNet-50 训练
查看>>
git flow 实操记录
查看>>