拓展方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拓展方法相关的知识,希望对你有一定的参考价值。

经常会看到以下形式的代码:

var persons = new List<Person>() { new Person() { IQ = 100 }, new Person() { IQ = 200 } };
persons.Where(p => p.IQ > 120).ToList().ForEach(p =>
{
    //Console.WriteLine(p.IQ);
});

注意这里 persons.Where 中的 Where,当去掉 using System.Linq 之后,会发现persons失去了Where方法;

 

--拓展方法登场--

 

1.什么是拓展方法:

  拓展方法是一种特殊的 ‘静态方法’,它能向现有数据类型 ‘动态’ 添加新方法,而且无需修改原类型;

2.如何创建拓展方法:

  1.拓展方法需要是静态的,且要放在一个非泛型的静态类中;

  2.方法的第一个参数为 ‘this 类型 形参’ ;

3.举例说明

1.新建一个Person类,此时Person只有一个IQ属性,没有任何方法;
public class Person
{
    public int IQ = 100;
}

2.为Person添加一个Study方法,每次学习则IQ+1;
public static class PersonExtend
{
    public static Person Study(this Person person)
    {
        person.IQ += 1;
        return person;
    }
}

3.现在Person已经‘拥有了’Study方法,可以写出如下代码:
var person = new Person();
Console.WriteLine(person.Study().IQ);

4.拓展方法的本质  ‘调用拓展方法就是在调用静态方法‘

通过反编译查看IL代码,可以发现 person.Study() 被编译成了:

call class test2.Person test2.PersonExtend::Study(class test2.Person)

也就是说,Person根本就没有 ‘拥有’ Study这个方法,

调用 person.Study() 等于是在调用 PersonExtend.Study(person)

可以这样写都是编译器的功劳;

5.拓展方法的好处

   1.可以为现有类型添加方法,但不用改动原有类型;

 2.使得方法的调用更能表达出代码的意图;

   3.???

6.一个比较实用的例子

//在批量操作时,经常需要把一组id用逗号连接起来,Linq中的Join方法却不是我们想要的
//于是自己拓展一下

namespace System.Linq
{
    public static class EnumerableExtend
    {
        public static string Join<T>(this IEnumerable<T> source, string separator)
        {
            if (source == null) return string.Empty;

            var result = "";

            foreach (var item in source)
            {
                result += item.ToString() + separator;
            }

            return result.TrimEnd(separator.ToCharArray());
        }
    }
}

 

more.. http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html

 

以上是关于拓展方法的主要内容,如果未能解决你的问题,请参考以下文章

JS最佳实践

sublime Text emmet插件使用手册

springboot 底层点的知识

springboot 底层点的知识

VSCode自定义代码片段—— 数组的响应式方法

VSCode自定义代码片段10—— 数组的响应式方法