扩展方法为我们带来了什么

一 发现问题

     扩展方法的思考来源于这样的一次经历:在项目中开发程序时,经常这样使用List<T>Dictionary<K,V>。

<span style="white-space:pre">	</span>    List<string> listTest = new List<string>();
            listTest.ForEach(item =>
                {
                    //方法体略
                });
            Dictionary<string, string> dicTest = new Dictionary<string, string>();
            dicTest.ForEach(item =>
                {
                    //方法体略
                });

二 提出问题

    使用的时候也从来没想过,为什么可以这么用,底层是怎么实现的,直到……..

          有那么一次,我自己写了个小项目,没有使用平台的类库,突然发现List<T>还可以这么使用,但是Dictionary<K,V>却不可以使用这个方法了,这是怎么回事呢?虽然直接使用迭代器完全可是实现相同的功能,但是本着不讲究是发现问题的源动力,我还是(ˇ?ˇ) 想~一探究竟。

        首先F12查看List<T>的底层,发现是这么实现的:

public class List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
    {
<span style="white-space:pre">	</span>public void ForEach(Action<T> action)
        {
            if (action == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
            }
            int num = this._version;
            for (int i = 0; i < this._size; i++)
            {
                if ((num != this._version) && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
                {
                    break;
                }
                action(this._items[i]);
            }
            if ((num != this._version) && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
            {
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
            }
        }
}

三 分析问题

          在泛型集合类中,直接写了这个方法的实现,所以可以由对象直接调用这个方法。而Dictionart<K,V>是怎么实现的呢?

<span style="white-space:pre">	</span>public static class IEnumerableExtension
	{
	<span style="white-space:pre">	</span>   public static void ForEach<T>(this IEnumerable<T> data, Action<T> action)
			{
				if (data != null && action != null)
				{
					foreach (T item in data)
					{
						action(item);
					}
				}
			}
	}

这个方法及实现并不是直接写到了字典类或者父类中,原来这是一个扩展类。那么扩展类究竟是怎么回事呢?我们平时会用到吗?应该如何使用呢?

四 理论支持        

          CSDN官方解释:扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其它方式修改原始类型。

         这里的添加带有双引号,原文已经说了,它并不是真正的给类型添加方法,而只是在程序中对它进行了扩展,所以并不需要重新编译和发布底层类库。

         好了,理论支持有了,来个实践,选用网上已经实现的例子:string类型有个IsNullOrEmpty方法判断字符串是否为null或为空,比如:

<span style="white-space:pre">	</span>    string strTest = string.Empty;
            bool resultIsNullOrEmpty = strTest.IsNullOrEmpty();
           现在,我们还需要进一步判断,赋值内容字符串是否为空字符串。代码如下:
    public static class ExtentdHelper
    {
        public static bool strIsNullOrWhiteSpace(this string str)
        {
            bool strIsNullOrWhiteSpace = false;
            if (string.IsNullOrEmpty(str) || str.Length == 0)
            {
                strIsNullOrWhiteSpace = true;
            }

            return strIsNullOrWhiteSpace;
        }
    }
<span style="white-space:pre">	</span>static void Main(string[] args)
        {
            string strTest = "";
            Console.WriteLine(strTest.IsNullOrWhiteSpace());
            Console.ReadKey();
        }

效果图:



扩展方法的约束:

1 扩展方法必须是静态方法,类必须是静态类,但它是通过实例调用的。

2 第一个参数必须有this关键字,用于确定扩展方法的目的类型。

3可以使用扩展类或接口,但是不能重写扩展方法。

五 解决问题

    好了,理论支持有了,我们回头看文章开头小编提出的问题,如何给Dictionary<K,V>编写这个扩展方法呢?

public static class ExtentdHelper
    {
<span style="white-space:pre">	</span>public static void ForEach<T>(this IEnumerable<T> data ,Action<T> action)
        {
            if (data != null && action != null)
            {
                foreach (T item in data)
                {
                    action(item);
                }
            }
        }

    }
   调用这个扩展方法:
<span style="white-space:pre">	</span>static void Main(string[] args)
        {
            Dictionary<string, string> dicTest = new Dictionary<string, string>();
            dicTest.Add("1","a");
            dicTest.Add("2","b");
            dicTest.Add("3","c");
            dicTest.ForEach(item =>
                {
                    Console.WriteLine("key: " + item.Key + "   value: " + item.Value);
                });

            Console.ReadKey();
        }

效果图:


六 总结:

    扩展方法好处:

1 减少程序中臃肿的代码,使代码更加简洁,更具阅读性。

2 可以在不继承和重写的情况下扩展类型的功能,使程序结构更加灵活。

3 为一些不能不能被继承或修改的类或接口(比如string或第三方控件中的某些类),提供了功能扩展的可能。







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值