前言:上篇 序列化效率比拼——谁是最后的赢家Newtonsoft.Json 介绍了下序列化方面的知识。看过Demo的朋友可能注意到了里面就用到过泛型的扩展方法,本篇打算总结下C#扩展方法的用法。博主打算分三个层面来介绍这个知识点,分别是:.Net内置对象的扩展方法、一般对象的扩展方法、泛型对象的扩展方法。

什么是扩展方法?回答这个问题之前,先看看我们一般情况下方法的调用。类似这样的通用方法你一定写过:

        static void Main(string[] args)
{ string strRes = "2013-09-08 14:12:10";
var dRes = GetDateTime(strRes);
} //将字符串转换为日期
public static DateTime GetDateTime(string strDate)
{
return Convert.ToDateTime(strDate);
} //得到非空的字符串
public static string GetNotNullStr(string strRes)
{
if (strRes == null)
return string.Empty;
else
return strRes;
}

或者在项目中有一个类似Utils的工具类,里面有多个Helper,例如StringHelper、XmlHelper等等,每个Helper里面有多个static的通用方法,然后调用的时候就是StringHelper.GetNotNullStr("aa");这样。还有一种普通的用法就是new 一个对象,通过对象去调用类里面的非static方法。反正博主刚开始做项目的时候就是这样写的。后来随着工作经验的累积,博主看到了扩展方法的写法,立马就感觉自己原来的写法太Low了。进入正题。

1、.Net内置对象的扩展方法

.Net内部也有很多定义的扩展方法,例如我们Linq常用的Where(x=>x==true)、Select()等等。当你转到定义的时候你很容易看出来:public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)。当然我们也可以给.Net对象新增扩展方法,比如我们要给string对象加一个扩展方法(注意这个方法不能和调用的Main方法放在同一个类中):

        public static string GetNotNullStr(this string strRes)
{
if (strRes == null)
return string.Empty;
else
return strRes ;
}

然后在Main方法里面调用:

        static void Main(string[] args)
{
string strTest = null;
var strRes = strTest.GetNotNullStr();
}

简单介绍:public static string GetNotNullStr(this string strRes)其中this string就表示给string对象添加扩展方法。那么在同一个命名空间下面定义的所有的string类型的变量都可以.GetNotNullStr()这样直接调用。strTest.GetNotNullStr();为什么这样调用不用传参数,是因为strTest就是作为参数传入到方法里面的。你可以试试。使用起来就和.Net framework定义的方法一样:

当然除了string,你可以给.Net内置的其他对象加扩展方法,例如给DataGridViewRow的扩展方法:

//DataGridViewRow的扩展方法,将当前选中行转换为对应的对象
public static T ToObject<T>(this DataGridViewRow item) where T:class
{
var model = item.DataBoundItem as T;
if (model != null)
return model;
var dr = item.DataBoundItem as System.Data.DataRowView;
model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });//反射得到泛型类的实体
PropertyInfo[] pro = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);
Type type = model.GetType();
foreach (PropertyInfo propertyInfo in pro)
{
if (Convert.IsDBNull(dr[propertyInfo.Name]))
{
continue;
}
if (!string.IsNullOrEmpty(Convert.ToString(dr[propertyInfo.Name])))
{
var propertytype = propertyInfo.PropertyType;
}
}
return model;
}

这样看上去就像在扩展.Net Framework。有没有感觉有点高大上~

2、一般对象的扩展方法

和Framework内置对象一样,自定义的对象也可以增加扩展方法。直接上示例代码:

    public class Person
{
public string Name { set; get; }
public int Age { set; get; }
}
        //Person的扩展方法,根据年龄判断是否是成年人
public static bool GetBIsChild(this Person oPerson)
{
if (oPerson.Age >= )
return false;
else
return true;
}

Main方法里面调用:

var oPerson1 = new Person();
oPerson1.Age = ;
var bIsChild = oPerson1.GetBIsChild();

和string扩展方法类似,就不多做解释了。

3、泛型对象的扩展方法

除了上面两种之外,博主发现其实可以定义一个泛型的扩展方法。那么,是不是所有的类型都可以直接使用这个扩展方法了呢?为了保持程序的严谨,下面的方法可能没有实际意义,当开发中博主觉得可能存在这种场景:

public static class DataContractExtensions
{
//测试方法
public static T Test<T>(this T instance) where T : Test2
{
T Res = default(T);
try
{
Res.AttrTest = instance.AttrTest.Substring(0,2);
//其他复杂逻辑... }
catch
{ }
return Res;
} } public class Test2
{
  public string AttrTest { set; get; }
}

使用扩展方法有几个值得注意的地方:

(1)扩展方法不能和调用的方法放到同一个类中

(2)第一个参数必须要,并且必须是this,这是扩展方法的标识。如果方法里面还要传入其他参数,可以在后面追加参数

(3)扩展方法所在的类必须是静态类

(4)最好保证扩展方法和调用方法在同一个命名空间下

可能你第一次使用这个会觉得很别扭。你也许会说扩展方法和我以前用的static方法无论从代码实现还是算法效率都差不多嘛,是的!确实差不多,但使用多了之后会发现它确实能帮你省去很多代码。

C#扩展方法知多少的更多相关文章

  1. .NET 扩展方法 (二)

    上一篇随笔 .NET 扩展方法 (一) 已经对 扩展方法有了大致的介绍,这篇算是一个补充,让我们来看一下扩展方法的几个细节: 一.扩展方法具有继承性 当使用扩展方法扩展一个类型的时候,其也扩展了派生类 ...

  2. Python扩展方法一二事

    前言 跟着一个有强迫症的老板干活是一件极其幸福的事情(你懂的).最近碰到一个问题,简单的说就是对一个对象做出部分修改后仍然返回此对象,于是我就写了一个方法,老板看了之后只有一句话:不雅观,改成直接对此 ...

  3. dynamic动态类型的扩展方法

    对于一个动态类型来说,你可以认为它包含任意成员,它们都能通过编译.但到了运行时,到底是否拥有这些成员,就真相大白了.如 dynamic test = ; Console.Write(test.Name ...

  4. C# Note21: 扩展方法(Extension Method)及其应用

    前言 今天在开会时提到的一个概念,入职3个多月多注重在项目中使用C#的编程知识,一直没有很认真地过一遍C#的全部语法,当我们新人被问及是否了解Extension Method时,一时之间竟不能很通俗准 ...

  5. c#扩展方法简单

    扩展方法 怎样知道的. 这还得从项目的本身说起.该项目是一套的微软底层架构上搭建起来的. 全部的框架以及控件的封装,数据的传递方法都是总体的框架封装好的. 对经常使用的dropwodnlist控件的数 ...

  6. .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

    .NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法 0x00 为什么需要Map(MapWhen)扩展 如果业务逻辑比较简单的话,一条主管道就够了,确实用不到 ...

  7. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  8. 为IEnumerable<T>添加RemoveAll<IEnumerable<T>>扩展方法--高性能篇

    最近写代码,遇到一个问题,微软基于List<T>自带的方法是public bool Remove(T item);,可是有时候我们可能会用到诸如RemoveAll<IEnumerab ...

  9. C#的扩展方法解析

    在使用面向对象的语言进行项目开发的过程中,较多的会使用到“继承”的特性,但是并非所有的场景都适合使用“继承”特性,在设计模式的一些基本原则中也有较多的提到. 继承的有关特性的使用所带来的问题:对象的继 ...

随机推荐

  1. Sublime Text 2 windows8安装插件失败解决

    事件是这样的: 1.安装Package Control组件后, 2.调出Install Package选项安装插件,状态栏显示成功, 3.但打开Packages目录也看不到,Sublime插件管理也没 ...

  2. jQuery静态方法noop,camelCase,nodeName,trim使用和源码分析

    noop方法 jQuery.noop()函数是一个空函数,它什么也不做. 当某些时候你需要传入函数参数,而且希望它什么也不做的时候,你可以使用该函数,也无需再新建一个空的函数. 示例: // 传入一个 ...

  3. 基于git diff进行的eslint代码检测

    缘起 在项目中, 通常都会使用代码检测工具来规范团队的代码风格, 比如eslint.随着代码的不断增加, eslint进行代码检测的时间也越来越久.每次检测的时候, 需要检测的文件和实际检测的文件极度 ...

  4. Ajax表单异步上传(包括文件域)

    起因 做前台页面时,需要调用WebAPI的Post请求,发送一些字段和文件(相当于把表单通过ajax异步发送出去,得到返回结果),然后得到返回值判断是否成功. 尝试 先是尝试了一下 "jQu ...

  5. HTML 迷宫

    今天补个遗,将很久以前研究 HTML5 的时候写的生成迷宫.迷宫寻路程序整理出来. 下载链接在文章最后. 简介 为什么要做这个 HTML5 迷宫程序?因为我喜欢.我愿意.也是向老程序员学习(见第5节) ...

  6. JavaScript异步编程(2)- 先驱者:jsDeferred

    JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,它来自于CommonJS小组的努力:Promise/A+规范. 研究javascri ...

  7. 在Autodesk应用程序商店发布基于浏览器的Web应用程序

    你一定已经听说过Autodesk应用程序商店了,通过Autodesk应用程序商店,你可以免费下载或购买来自全球的优秀开发者发布的应用程序,来帮助你更快更方便的完成你的工作.而且作为开发者,您也可以在A ...

  8. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  9. Android中GridView通过自定义适配器(未优化)实现图文视图排列

    Android中GridView组件用来以网格方式排列视图,与矩阵类似,当屏幕上有很多元素(文字.图片或其他元素)需要显示时,可以使用该组件.下面我们通过代码实现如下图例(为了方便截图,将事件处理(土 ...

  10. UIScrollView出现位移问题

    啦啦啦啦啦~~~ UINavigationController和UIScrollView一起使用时会导致UIScrollView位置偏移 情况:UINavigationController的视图上的第 ...