项目中遇到的扩展方法-总结和分享
概述:
本篇是对工作中遇到的扩展方法的总结,好记性不如乱笔头,先记下来,以后遇到类似问题,如果忘了,可以看下博客。
一、问题描述:
在项目中遇到一个问题,就是要将左边的代码替换为右边的代码,右边代码是对左边代码的封装,所以右边的代码更简便些。
dataReader.IsDBNull(2) ? (string)null : dataReader.GetString(2).Trim(); | dataReader.MyGetDataString(2); |
dataReader的类型是System.Data.SqlClient.SqlDataReader,这个是Framework类库里面的
而MyGetDataString是项目中自定义的方法,按照现有的知识,dataReader.MyGetDataString(2)这行code在编译时,会报找不到定义才对,
那么这里是怎么调用到了这个MyGetDataString方法的呢????
二、问题分析
带着这个问题,我们首先来看看这个方法在哪定义的
MyGetDataString方法定义在MyProject.Common.Extensions.DataReaderExtensions 类中
1 2 3 4 | public static string MyGetDataString( this IDataRecord dataRecorder, int index) { return GetDataString(dataRecorder, index); } |
这个方法有什么特别的呢???
通过观察,我们发现参数列表里面多加了一个this关键字。这种语法在.NET中称作扩展方法。
扩展方法:使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异。
三、定义和调用扩展方法
1. 定义一个静态类以包含扩展方法。该类必须对客户端代码可见。
2. 将该扩展方法实现为静态方法,并使其至少具有与包含类相同的可见性。
3. 该方法的第一个参数指定方法所操作的类型;该参数必须以 this 修饰符开头。
4. 在调用代码中,添加一条 using 指令以指定包含扩展方法类的命名空间。
5. 按照与调用类型上的实例方法一样的方式调用扩展方法。
四、例子
1.扩展类的方法
1.定义扩展类MyExtension,定义扩展方法GetMessage
1 2 3 4 5 6 7 8 9 10 11 | namespace ExtensionMethods { public static class MyExtension { public static string GetMessage( this string str) { str = str + "123" ; return str; } } } |
2.调用扩展方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using System; using ExtensionMethods; namespace ExtensionMethods { class Program { static void Main( string [] args) { string s = "abc" ; Console.WriteLine(s.GetMessage()); } } } |
2.扩展接口方法
1. 定义一个接口IFly
1 2 3 4 5 6 7 | namespace ExtensionMethods { public interface IFly { void FastFly(); } } |
2. 定义一个Duck类继承IFly接口
1 2 3 4 5 6 7 8 9 10 11 12 | using System; namespace ExtensionMethods { class Duck:IFly { public void FastFly() { Console.WriteLine( "Fast Flay" ); } } } |
3. 定义扩展类FlyExtension,定义扩展方法LowSpeedFly
1 2 3 4 5 6 7 8 9 10 11 12 | using System; namespace ExtensionMethods { public static class FlyExtension { public static void LowSpeedFly( this IFly flyInterface) { Console.WriteLine( "Low speed fly" ); } } } |
4. 调用扩展方法
1 2 | Duck duck = new Duck(); duck.LowSpeedFly(); |
注意:
1. 可以使用扩展方法来扩展类或接口,但不能重写扩展方法。
2. 与接口或类方法具有相同名称和签名的扩展方法永远不会被调用。
3. 编译时,扩展方法的优先级总是比类型本身中定义的实例方法低。换句话说,如果某个类型具有一个名为 Process(int i) 的方法,而你有一个具有相同签名的扩展方法,则编译器总是绑定到该实例方法。当编译器遇到方法调用时,它首先在该类型的实例方法中寻找匹配的方法。如果未找到任何匹配方法,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到的第一个扩展方法。
参考资料:
扩展方法(C# 编程指南): https://msdn.microsoft.com/zh-cn/library/bb383977.aspx
作 者:
Jackson0714
出 处:http://www.cnblogs.com/jackson0714/
关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?