扩展方法

扩展方法是一个静态类的静态方法。开发者可以像调用其他类的实例方法(对象.方法(),这个就是实例方法)一样去调用扩展方法。比如我们平常说ToString就是一个实例方法了,任何对象都可以直接对象名点出来。但是如果我们需要写一个ToInt(),我们就没办法通过对象名来点出来了。现在有了扩展方法,我们就可以去实现这个功能。

实例方法和静态方法。实例方法是通过对象来调用的,而静态方法则是通过类名来调用的。比如字符串中的ToUpper就是实例方法,而字符串中的Format则是静态方法。静态方法是通过类名string.Format来调用的,而实例方法则是通过对象名来调用 str.ToUpper()。

扩展方法解决的问题:有了扩展方法,我们才可以使用一种新型的代码思想,就是链式编程。比如我现在要把一个字符串先转换为大写,又裁剪一部分字符,我们可以这样 str.ToUpper().SubString()。另外我们知道Enumerable类里面有个Where方法,他可以传入一个Enumerable数据,然后返回一个Enumerable数据。那么我们调用的时候往往是这样:

Enumerable e = {"1111","222","333"};
Enumerable.Where(e, m => m.StartWith("1"));Code language: PHP (php)

这样我们可能觉得没什么,但是如果有多个Where呢?我们可能是这样:

Enumerable e = {"1111","222","333"};
Enumerable e1 = Enumerable.Where(e, m => m.StartWith("1"));
Enumerable e2 = Enumerable.Where(e1, m => m.StartWith("1"));
Enumerable e3 = Enumerable.Where(e2, m => m.StartWith("1"));Code language: PHP (php)

这样的代码是不是很臃肿。

解决方法就是扩展方法:

e.Where(表达式).Where(表达式).Where(表达式);Code language: CSS (css)

每一个Where返回来是一个Enumerable,然后本身又去调用Where方法。

扩展方法需要定义在静态方法里面。扩展方法需要是静态方法。扩展方法的第一个参数需要是带上this。扩展方法的第一个参数是什么类型,就是什么类型的扩展方法。比如:

public static class StringExtends
{
    public static double ToDouble(this string s)
    {
        return Double.Parse(s);
    }

    //还可以带上其他参数
    public static double ToDouble(this string s, double def)
    {
        double d = 0;
        // Double.Try...
    }
}Code language: PHP (php)

调用的时候:

string str = "23";
str.ToDouble();
str.ToDouble(12.1);Code language: JavaScript (javascript)

本集代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ConsoleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var person = new Person();
            person.Say(); //实例方法
            //person.SayEx();
            Person.SayEx(); //静态方法

            string str = "www.bamn.cn";
            Console.WriteLine(str.ToUpper());
            Console.WriteLine(string.Format("这里是{0}", "北盟网校"));

            string num = "12";
            Console.WriteLine(num.ToString());
            Console.WriteLine(num.ToInt()); //通过对象点出来
            Console.WriteLine(StringExtend.ToInt(num)); //通过静态方法调用
            Console.WriteLine(num.ToInt(12)); //对象自己就作为第一个参数了
            Console.WriteLine(StringExtend.ToInt(num, 12));

            Console.WriteLine(ToInt(num));
            Person p = new Person();
            Console.WriteLine(p.ToInt());

            var e = new string[] { "1111", "222", "333" };
            IEnumerable<string> e2 = Enumerable.Where(e, m => m.StartsWith("2"));
            IEnumerable<string> e3 = Enumerable.Where(e2, m => m.StartsWith("e"));

            var e1 = e.Where(m => m.StartsWith("22")).Where(m => m.StartsWith("333"));
            Console.ReadKey();
        }

        public static int ToInt(string str)
        {
            return int.Parse(str);
        }
    }

    public static class StringExtend
    {
        public static int ToInt(this string str) //str就是我们的对象 比如上面的num
        {
            return int.Parse(str);
        }

        public static int ToInt(this string str, int a) //str就是我们的对象 比如上面的num
        {
            try
            {
                return int.Parse(str);
            }
            catch (Exception)
            {
                return a;
            }
        }
    }

    internal class Person
    {
        public Person()
        {
        }

        public void Say()
        {
            Console.WriteLine("实例方法");
            SayEx();
        }

        public static void SayEx()
        {
            //Say()
            Console.WriteLine("静态方法");
        }

        public string num = "12";

        public int ToInt()
        {
            return int.Parse(num);
        }
    }

    public class Address
    {
        public string city;
        public string state;
    }
}Code language: PHP (php)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注