扩展方法是一个静态类的静态方法。开发者可以像调用其他类的实例方法(对象.方法(),这个就是实例方法)一样去调用扩展方法。比如我们平常说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)
Previous: 关键字变量var、对象初始化和匿名类型
Next: Inner Join表连接