项目中遇到的扩展方法-总结和分享

概述:

本篇是对工作中遇到的扩展方法的总结,好记性不如乱笔头,先记下来,以后遇到类似问题,如果忘了,可以看下博客。

一、问题描述:

在项目中遇到一个问题,就是要将左边的代码替换为右边的代码,右边代码是对左边代码的封装,所以右边的代码更简便些。

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  类中

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

namespace ExtensionMethods
{
    public static class MyExtension
    {
        public static string GetMessage(this string str)
        { 
            str = str + "123";
            return str;
        }
    }
}

2.调用扩展方法

using System;
using ExtensionMethods;
 
namespace ExtensionMethods
{
    class Program
    {
        static void Main(string[] args)
        {
            string s = "abc";
            Console.WriteLine(s.GetMessage());
        }
    }
}

2.扩展接口方法

 1. 定义一个接口IFly

namespace ExtensionMethods
{
    public interface IFly
    {
        void FastFly();
    }
}

 2. 定义一个Duck类继承IFly接口

using System;
 
namespace ExtensionMethods
{
    class Duck:IFly
    {
        public void FastFly()
        {
            Console.WriteLine("Fast Flay");
        }
    }
}

 3. 定义扩展类FlyExtension,定义扩展方法LowSpeedFly

using System;
 
namespace ExtensionMethods
{
    public static class FlyExtension
    {
        public static void LowSpeedFly(this IFly flyInterface)
        {
            Console.WriteLine("Low speed fly");
        }
    }
}

4. 调用扩展方法  

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/ 关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教! 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。 特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我 声援博主:您的鼓励是作者坚持原创和持续写作的最大动力!

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏hbbliyong

C#基础知识回顾-- 反射(1)

反射(reflection)是一种允许用户获得类型信息的C#特性。术语“反射”源自于它的工作方式: Type对象映射它所代表的底层对象。对Type对象进行...

35110
来自专栏Jackson0714

PHP内核之旅-3.变量

1504
来自专栏绿巨人专栏

TypeScript中的怪语法

4855
来自专栏我是攻城师

Apache Pig学习笔记之内置函数(三)

4414
来自专栏Jerry的SAP技术分享

使用JavaScript ES6的新特性计算Fibonacci(非波拉契数列)

Java程序员面试系列-什么是Java Marker Interface(标记接口)

1053
来自专栏Ryan Miao

java基础面试题

参考:http://blog.csdn.net/jackfrued/article/details/44921941 说未经允许不转载,我只好参考了。 1.面向...

3715
来自专栏飞雪无情的博客

从Java到Golang快速入门

Golang从09年发布,中间经历了多个版本的演进,已经渐渐趋于成熟,并且出现了很多优秀的开源项目,比如我们熟知的docker,etcd,kubernetes等...

1133
来自专栏佳爷的后花媛

java学习要点

作为一个程序员,在找工作的过程中,都会遇到笔试,而很多笔试里面都包括java,尤其是作为一个Android开发工程师,java是必备技能之一.所以为了笔试过程中...

3395
来自专栏程序员互动联盟

【编程基础】聊聊C语言-兵马未动粮草先行(1)

上一篇我们讲的聊聊C语言-我的地盘我做主,相信大家对变量的存储类型和变量的作用域有了一定的了解。现在我们马上公布上期的答案如下: #include<stdio....

3358
来自专栏绿巨人专栏

TypeScript中的怪语法

1193

扫码关注云+社区

领取腾讯云代金券