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

概述:

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

一、问题描述:

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

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) 的方法,而你有一个具有相同签名的扩展方法,则编译器总是绑定到该实例方法。当编译器遇到方法调用时,它首先在该类型的实例方法中寻找匹配的方法。如果未找到任何匹配方法,编译器将搜索为该类型定义的任何扩展方法,并且绑定到它找到的第一个扩展方法。

时间: 2024-10-09 10:54:31

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

Vue-Router路由Vue-CLI脚手架和模块化开发 之 在单文件组件项目中定义数据、方法和组件之间的相互引用

定义数据 根据上一篇博文配置项目的结构的基础上继续进行优化: 在app.vue中的导出模块/组件部分设置其属性: export default{//导出模块/组件 data(){ return{ name:'perfect', count:0 } }, 在一个template标签中进行调用: <template> <div> <h2> 欢迎来到perfect*的博客园!!!</h2> <h3>{{name}}</h3> </te

VS编译linux项目生成静态库并在另一个项目中静态链接的方法

VS2017也推出很久了,在单位的时候写linux的服务端程序只能用vim,这让用惯了IDE的我很难受. 加上想自己撸一套linux上的轮子,决定用VS开工远程编写调试linux程序. 在windows下编写静态库并在另一个项目中引用很简单 新建项目的时候选择静态库,进去把代码撸好,即可编译出静态库*.lib 随后在希望使用该静态库的项目中设置一下链接器"附加库目录"为"../Debug"(和你的输出路径有关),然后添加"附加依赖项"静态库名.l

分享.NET系统开发过程中积累的扩展方法

.NET 3.5提供的扩展方法特性,可以在不修改原类型代码的情况下扩展它的功能.下面分享的这些扩展方法大部分来自于Code Project或是Stackoverflow,.NET为此还有一个专门提供扩展方法的网站(extensionMethod). 涵盖类型转换,字符串处理,时间转化,集合操作等多个方面的扩展. 1  TolerantCast 匿名类型转换 这个需求来源于界面中使用BackgroundWorker,为了给DoWork传递多个参数,又不想定义一个类型来完成,于是我会用到Tolera

ABP框架源码中的Linq扩展方法

文件目录:aspnetboilerplate-dev\aspnetboilerplate-dev\src\Abp\Collections\Extensions\EnumerableExtensions.cs using System; using System.Collections.Generic; using System.Linq; namespace Abp.Collections.Extensions { /// <summary> /// Extension methods for

为何使用二次参数拦截器栈,,为何需要在beforeInput() [即prepareInput(),本项目中分装为beforeInput()方法] 方法中获取employee

因为,使用模型驱动,可以将不为空的employee压入栈顶,从而使得页面中以employee的属性名作为name的Struts标签元素能够获取到对应属性名的属性值,在点击修改后,可以实现回显. 具体的: 由于modelDriven拦截器先于input()方法执行,因此需要将获取employee的方法提前到modelDriven拦截器之前,即在prepareInput()方法获取employee,此时employee就不空了,再在后面执行到modelDriven拦截器时就将employee对象放入

免费生成二维码接口,可直接嵌入到web项目中,附带嵌入方法,任意颜色二维码,任意大小二维码!

在线体验连接:http://www.zhaimaojun.top/qrcode/ 你是否在项目中寻找方便而且免费的可以直接嵌入到项目中的二维码生成工具呢?你找到了这里,说明你已经找到了!不要犹豫直接拿去用吧! 体验的页面预览: 好了 废话不多说,接下来示范两种嵌入方式一种嵌入到网页的一种嵌入到c#的web程序中,可以直接下载为文件. 第一种,直接下载二维码图片,通过浏览器自带的下载器或者浏览器里面直接输入地址: 直接在下载栏或者地址栏里输入: http://www.zhaimaojun.top/

在Unity3D项目中接入ShareSDK实现安卓平台微信分享功能(可使用ShareSDK默认UI或自定义UI)

最近公司的大厅要重做,我协助主程一起制作新大厅和新框架,前面制作的编辑器也派上了用场.等全部功能做完后我会再写一个复盘,这两天主程在忙于写热更新的功能,所以把接入分享SDK功能的任务交给了我,ShareSDK官网的文档比较分散,而且关于Unity的文档比较简略,所以还是有不少的坑.写篇博客分享一下,并加强理解记忆. 第一步,先去ShareSDK的官网下载最新版本的ShareSDK(完全免费).地址:http://www.mob.com/ 我们选择ShareSDK For Unity3D,页面会直

项目中使用libsodium扩展

前段时间研究了微信小微商户,地址:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_11 其接口操作中需要下载证书针对返回的密文用 AEAD_AES_256_GCM 算法解密 其中用到了 string sodium_crypto_aead_aes256gcm_decrypt ( string $ciphertext , string $ad , string $nonce , string $key ) 这个函数 但是这个

在项目中,多个方法会调用相同的sql语句,怎么解决各个方法的不同sql查询,解决冲突。

公司的代码中sql语句,可能会被多个方法进行调用,但是有的方法会关联到别的表,这样的话,如果修改不当,那么同样调用该sql语句的方法,会出现报错. 最近做的公司的一个功能,就出现这样一个问题,虽然本功能完成,但是调用该sql的其他方法,出现严重错误,虽然可以不同的方法些不同的sql语句,就可以解决该方法,但是公司的代码这样,痛另外一种方法解决. 该问题出现需求背景:这个需求是在做物流系统,这次要在前台页面显示的信息中增加一个字段,而要显示这个字段,就得在关联两张新表,所以在前台页面中增加一个in