C#秘密武器之扩展方法

为何要用扩展方法?

作为一个.NET程序猿,我们经常要跟.net自带类库或者第三方dll类库打交道,有时候我们未必能够通过反编译来查看它们的代码,但是我们通常需要给它们扩充一些新的功能,Helper类就应运而生了,我们开发出一个个的静态方法以方便调用。久而久之,我们封装的Helper类越来越多,但是这个Helper里边的方法不一定为每个开发人员所熟知,而且我们每每要敲击XXXHelper.XXX()这种类似的方法,其实这个XXXHelper完全是可以省略掉的,等于是我们每次都多写了这么一点东西。

有没有解决办法呢?扩展方法就是解决这个问题的。扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。它可以对现有类功能进行扩充,从而使该类型的实例具有更多的方法,伟大的LINQ就是用的这个东西实现的。

使用扩展方法的好处:

1、让方法调用回归面向对象本身,即方法是属于对象的,增强代码可读性

2、从一定程度上来说扩展方法让你的类库有了无限的可能性

扩展方法的应用

扩展方法必须遵守以下规则:

1.扩展类必须是静态非泛型的;

2.扩展方法必须是静态的

3.扩展方法的第一个参数必须以this开头,参数必须是原有类的类型

举个扩展方法的栗子:

我们经常需要对对象进行序列化,那么我们可以给对象object扩展一个这样的方法ToJSON

using Newtonsoft.Json;
namespace Ctrip.Json{
   public static class JsonHelper
   {
     public static string ToJson(this object obj)
     {
      string JsonStr = JsonConvert.SerializeObject(obj);
      return JsonStr;
     }
   }
}

调用:

using Ctrip.Json;

Student stu=new Student{Name="张三",Sex="男",Age=25};
string jsonString = stu.ToJson();

平时我们总是需要操作字符串类型,因此这里就送上一个string类型的扩展方法类库:

using System;

using System.Globalization;

using System.Reflection;

using System.Text;

using System.Text.RegularExpressions;

using Infrastructure.Common;

using Newtonsoft.Json;

namespace Infrastructure.Utility

{

    /// <summary>

    /// 字符串类型帮助类

    /// </summary>

    public static class StringHelper

    {

        /// <summary>

        /// Object对象序列化为Json字串

        /// </summary>

        /// <param name="obj"></param>

        /// <returns></returns>

        public static string ToJson(this object obj)

        {

            return JsonConvert.SerializeObject(obj);

        }

        /// <summary>

        /// Json字串反序列化为Object强类型

        /// </summary>

        public static T DeJson<T>(this string json)

        {

            return JsonConvert.DeserializeObject<T>(json);

        }

        /// <summary>

        /// 根据根据字符串转换成相对应的枚举子项

        /// </summary>

        /// <typeparam name="TEnum">枚举类型</typeparam>

        /// <param name="strEnumDescription">字符串</param>

        /// <returns>枚举子项</returns>

        public static TEnum ToEnum<TEnum>(this string strEnumDescription)

            where TEnum : struct

        {

            Type enumType = typeof(TEnum);

            TEnum[] enumValues = (TEnum[])Enum.GetValues(enumType);

            foreach (var enumValue in enumValues)

            {

                string strValue = enumValue.ToString();

                FieldInfo fieldinfo = enumValue.GetType().GetField(strValue);

                object[] objs = fieldinfo.GetCustomAttributes(typeof(EnumItemAttribute), false);

                if (objs.Length == 0)

                {

                    continue;

                }

                EnumItemAttribute enumItemAttribute = (EnumItemAttribute)objs[0];

                if (enumItemAttribute != null && string.Equals(enumItemAttribute.Description, strEnumDescription, StringComparison.CurrentCultureIgnoreCase))

                {

                    return enumValue;

                }

            }

            return default(TEnum);

        }

        /// <summary>

        /// 获得字符串的长度,一个汉字的长度为1

        /// </summary>

        public static int GetStringLength(string s)

        {

            if (!string.IsNullOrEmpty(s))

                return Encoding.Default.GetBytes(s).Length;

            return 0;

        }

        /// <summary>

        /// 获得字符串中指定字符的个数

        /// </summary>

        /// <param name="s">字符串</param>

        /// <param name="c">字符</param>

        /// <returns></returns>

        public static int GetCharCount(string s, char c)

        {

            if (s == null || s.Length == 0)

                return 0;

            int count = 0;

            foreach (char a in s)

            {

                if (a == c)

                    count++;

            }

            return count;

        }

        /// <summary>

        /// 获得指定顺序的字符在字符串中的位置索引

        /// </summary>

        /// <param name="s">字符串</param>

        /// <param name="order">顺序</param>

        /// <returns></returns>

        public static int IndexOf(string s, int order)

        {

            return IndexOf(s, ‘-‘, order);

        }

        /// <summary>

        /// 获得指定顺序的字符在字符串中的位置索引

        /// </summary>

        /// <param name="s">字符串</param>

        /// <param name="c">字符</param>

        /// <param name="order">顺序</param>

        /// <returns></returns>

        public static int IndexOf(string s, char c, int order)

        {

            int length = s.Length;

            for (int i = 0; i < length; i++)

            {

                if (c == s[i])

                {

                    if (order == 1)

                        return i;

                    order--;

                }

            }

            return -1;

        }

        #region 分割字符串

        /// <summary>

        /// 分割字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="splitStr">分隔字符串</param>

        /// <returns></returns>

        public static string[] SplitString(string sourceStr, string splitStr)

        {

            if (string.IsNullOrEmpty(sourceStr) || string.IsNullOrEmpty(splitStr))

                return new string[0] { };

            if (sourceStr.IndexOf(splitStr) == -1)

                return new string[] { sourceStr };

            if (splitStr.Length == 1)

                return sourceStr.Split(splitStr[0]);

            else

                return Regex.Split(sourceStr, Regex.Escape(splitStr), RegexOptions.IgnoreCase);

        }

        /// <summary>

        /// 分割字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <returns></returns>

        public static string[] SplitString(string sourceStr)

        {

            return SplitString(sourceStr, ",");

        }

        #endregion

        #region 截取字符串

        /// <summary>

        /// 截取字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="startIndex">开始位置的索引</param>

        /// <param name="length">子字符串的长度</param>

        /// <returns></returns>

        public static string SubString(string sourceStr, int startIndex, int length)

        {

            if (!string.IsNullOrEmpty(sourceStr))

            {

                if (sourceStr.Length >= (startIndex + length))

                    return sourceStr.Substring(startIndex, length);

                else

                    return sourceStr.Substring(startIndex);

            }

            return "";

        }

        /// <summary>

        /// 截取字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="length">子字符串的长度</param>

        /// <returns></returns>

        public static string SubString(string sourceStr, int length)

        {

            return SubString(sourceStr, 0, length);

        }

        #endregion

        #region 移除前导/后导字符串

        /// <summary>

        /// 移除前导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <returns></returns>

        public static string TrimStart(string sourceStr, string trimStr)

        {

            return TrimStart(sourceStr, trimStr, true);

        }

        /// <summary>

        /// 移除前导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <param name="ignoreCase">是否忽略大小写</param>

        /// <returns></returns>

        public static string TrimStart(string sourceStr, string trimStr, bool ignoreCase)

        {

            if (string.IsNullOrEmpty(sourceStr))

                return string.Empty;

            if (string.IsNullOrEmpty(trimStr) || !sourceStr.StartsWith(trimStr, ignoreCase, CultureInfo.CurrentCulture))

                return sourceStr;

            return sourceStr.Remove(0, trimStr.Length);

        }

        /// <summary>

        /// 移除后导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <returns></returns>

        public static string TrimEnd(string sourceStr, string trimStr)

        {

            return TrimEnd(sourceStr, trimStr, true);

        }

        /// <summary>

        /// 移除后导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <param name="ignoreCase">是否忽略大小写</param>

        /// <returns></returns>

        public static string TrimEnd(string sourceStr, string trimStr, bool ignoreCase)

        {

            if (string.IsNullOrEmpty(sourceStr))

                return string.Empty;

            if (string.IsNullOrEmpty(trimStr) || !sourceStr.EndsWith(trimStr, ignoreCase, CultureInfo.CurrentCulture))

                return sourceStr;

            return sourceStr.Substring(0, sourceStr.Length - trimStr.Length);

        }

        /// <summary>

        /// 移除前导和后导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <returns></returns>

        public static string Trim(string sourceStr, string trimStr)

        {

            return Trim(sourceStr, trimStr, true);

        }

        /// <summary>

        /// 移除前导和后导字符串

        /// </summary>

        /// <param name="sourceStr">源字符串</param>

        /// <param name="trimStr">移除字符串</param>

        /// <param name="ignoreCase">是否忽略大小写</param>

        /// <returns></returns>

        public static string Trim(string sourceStr, string trimStr, bool ignoreCase)

        {

            if (string.IsNullOrEmpty(sourceStr))

                return string.Empty;

            if (string.IsNullOrEmpty(trimStr))

                return sourceStr;

            if (sourceStr.StartsWith(trimStr, ignoreCase, CultureInfo.CurrentCulture))

                sourceStr = sourceStr.Remove(0, trimStr.Length);

            if (sourceStr.EndsWith(trimStr, ignoreCase, CultureInfo.CurrentCulture))

                sourceStr = sourceStr.Substring(0, sourceStr.Length - trimStr.Length);

            return sourceStr;

        }

        #endregion

    }

}

备注:

1、在vs的智能提示中,扩展方法是带有蓝色下滑箭头的

2、如果扩展方法和被扩展类中的方法相同,会怎么样?

扩展方法的优先级总是比类型本身中定义的实例方法低,所以与接口或类方法具有相同名称和签名的扩展方法永远不会被调用。

3、注意你是为哪个类型进行扩展,比如你是对string类型做扩展,还是对object类型、List<object>类型做扩展,一定要明确扩展的类型范围

4、是时候尝试将你的那些Helper类库转换成扩展方法了

5、当你苦于类库里没有你想要的方法时,那就大胆的扩展吧

总结:

扩展方法本身并不难,难点在于你是否能够恰到好处地使用它,也就是说你是否知道在某个合适的时候使用它。

C#秘密武器之扩展方法

时间: 2024-11-07 06:33:13

C#秘密武器之扩展方法的相关文章

margin负值 – 一个秘密武器

CSS盒模型中,margin是我们老熟悉的一个属性了, 它的负值你用过吗? 你知道margin负值的秘密武器吗?我们一起看看吧! 1.带竖线分隔的横向列表(例如:网站底部栏目) 传统的分隔符是使用 “|” 来实现的,弊端显而易见,不利于表现与结构的分离,同时增加了后台输出时的判断工作. 所以我们采用border-left 左边框来模拟分割线,然后通过margin-left:-1px隐藏掉第一个列表项的边框,父元素设置 overflow:hidden 来隐藏溢出部分,这样完美达到首尾无分割线的要求

有人说中文编辑是解决中国程序员编程效率的秘密武器,请问他是一个银弹吗?

一.“银弹” 首先在这里解释一下“银弹”的概念,顾名思义就是银质的子弹(Silver Bullet),是古老的欧洲民间传说中能杀死狼人的利器.当然现实中是没有狼人的,但现实中确实有银弹这个东西.而其意义也类似于能杀死狼人的最好办法.现实中的狼人可以是一个棘手的项目,或者一件不可能的事.而“银弹”就是指能解决这些事的方法,或者技术手段,被比喻为具有极端有效性的解决方法,作为杀手锏 .王牌等的代称. IBM大型机之父佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表

有人认为“中文编程”是解决中国程序员编程效率的秘密武器,请问它是一个“银弹”么?

有人认为“中文编程”是解决中国程序员编程效率的秘密武器,请问它是一个“银弹”么?首先,百度给出“银弹”是这样的解释:能杀死狼人的利器 在古老的传说里.狼人是不死的.想要杀死狼人有几种方法: 1.像杀死吸血鬼那样用木桩钉住狼人的心脏. 2.将月光遮住 3.用银子做的子弹射穿狼人的心脏或头 当然现实中是没有狼人的.但现实中确实有银弹这个东西.而其意义也类似于能杀死狼人的最好办法.现实中的狼人可以是一个棘手的项目,或者一件不可能的事.而“银弹”就是指能解决这些事的方法,或者技术手段. 我不认中文编程是

2.有人认为,“中文编程”是解决中国程序员编程效率的秘密武器,请问它是一个“银弹”么?

银色子弹(英文:Silver Bullet),或者称“银弹”“银质子弹”,指由纯银质或镀银的子弹.在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往被描绘成具有驱魔功效的武器,是针对狼人等超自然怪物的特效武器.后来银色子弹常被用做致命武器的代言词.被比喻为具有极端有效性的解决方法,作为杀手锏[1]  .最强杀招.王牌等的代称. IBM大型机之父佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表的一篇关于软件工程的经典论文,便以<没有银弹:软件工程的本

“中文编程”会是解决中国程序员编程效率的秘密武器,成为中国软件工程的“银弹”么?

一.“银弹” 首先在这里解释一下“银弹”的概念,顾名思义就是银质的子弹(Silver Bullet),是古老的欧洲民间传说中能杀死狼人的利器.当然现实中是没有狼人的,但现实中确实有银弹这个东西.而其意义也类似于能杀死狼人的最好办法.现实中的狼人可以是一个棘手的项目,或者一件不可能的事.而“银弹”就是指能解决这些事的方法,或者技术手段,被比喻为具有极端有效性的解决方法,作为杀手锏 .王牌等的代称. IBM大型机之父佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表

7. 有人认为,“中文编程”, 是解决中国程序员编程效率一个秘密武器,请问它是一个 “银弹” 么?

银色子弹(英文:Silver Bullet),或者称“银弹”“银质子弹”,指由纯银质或镀银的子弹.在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往被描绘成具有驱魔功效的武器,是针对狼人等超自然怪物的特效武器.后来银色子弹常被用做致命武器的代言词.被比喻为具有极端有效性的解决方法,作为杀手锏.最强杀招.王牌等的代称. IBM大型机之父佛瑞德·布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表的一篇关于软件工程的经典论文,便以<没有银弹:软件工程的本质性与附属

有人认为,“中文编程”,是解决中国程序员编程效率的一个秘密武器,请问它是一个“银弹“吗?

银色子弹(英文:Silver Bullet),或者称“银弹”“银质子弹”,指由纯银质或镀银的子弹.在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往被描绘成具有驱魔功效的武器,是针对狼人,吸血鬼等超自然怪物的特效武器.后来银色子弹常被用做致命武器的代言词.被比喻为具有极端有效性的解决方法,作为杀手锏.最强杀招.王牌等的代称. IBM大型机之父弗瑞德.布鲁克斯(Frederick P. Brooks, Jr.)在1986年发表的一篇关于软件工程的经典论文,便以<没有银弹:软件工程的本质

丰胸产品什么品牌好,亦姿佳美乳霜练就D奶的秘密武器

爱美之心,人皆有之,试问谁不爱美,谁不想着有副好身材呢?可是自从生完宝宝以后,我的胸部就开始缩水.下垂,30岁的年纪却像老太太一样,真的很是烦恼.经过一番思想斗争之后,我决定丰胸,而且最终也成功了.丰胸产品什么品牌好?还在为你平平的飞机场发愁吗?还是没有办法挺胸找回自信吗?『亦姿佳美乳霜』让你靓丽自信! 丰胸产品什么品牌好 以前我的胸部很小,身材一般,连找工作都会遇到难题,自从用了亦姿佳后,另我具有傲人的身姿,工作更是轻而易举,这都是亦姿佳的功劳,闲话就不说了,来看看我的丰胸经历吧. 刚走出校园

团队高效率协作开发的秘密武器-APIDOC

团队高效率协作开发的秘密武器 1.前言 在团队协作开发中,不知道各位有没有遇到这样的问题: l 新人接手了项目代码,因没有项目文档,只能靠追踪路由,寻读代码分析业务逻辑 l 前端同学写好了页面,苦等后端接口规则,来写交互请求,获取数据 l 测试同学写测试用例,因项目还没完成,而迟迟无法开工 如何愉快地解决以上问题呢?答案就是它——APIDOC. 2.APIDOC是什么 APIDOC是一款Web API文档生成工具,可以根据代码注释自动生成静态html网页文档,不仅支持项目版本号,还支持接口版本号