扩展方法
Posted CS讷于言而敏于行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展方法相关的知识,希望对你有一定的参考价值。
有时我们没有源代码,但是又需要在某个类中添加一些需要的方法,如何在不改变类源码的情况下,为类添加一个或多个方法呢?扩展方法就为我们提供了一个思路
如果我们想要判断一个字符串是否为数字,我们需要先写一个方法对其进行判断,比如下边的代码:
1 class Program 2 { 3 /// <summary> 4 /// 判断字符串是否是数字 5 /// </summary> 6 /// <param name="str">需要判断的字符串</param> 7 /// <returns>判断结果</returns> 8 static bool IsInt(string str) 9 { 10 string pattern = @"^[1-9]\d*$"; 11 Regex regex = new Regex(pattern); 12 if (regex.IsMatch(str)) 13 return true; 14 else 15 return false; 16 } 17 18 static void Main(string[] args) 19 { 20 Console.WriteLine(IsInt("a329")); 21 22 Console.ReadKey(); 23 } 24 }
但是如果string类型中有一个ToInt()方法来帮我判断就好了,所以我们就可以在一个新的类中通过扩展方法的方式为string类型添加一个方法。
1 /// <summary> 2 /// 定义一个静态类,在该类中为string类型添加一个扩展方法IsInt()方法 3 /// </summary> 4 static class StringExtension 5 { 6 /// <summary> 7 /// 为string类型添加的扩展方法,this关键字后边的string,指的就是要将该方法添加到string类中,如果方法需要传入其他参数,直接写在后边就行了 8 /// </summary> 9 /// <param name="str"></param> 10 /// <returns></returns> 11 public static bool IsInt(this string str) 12 { 13 string pattern = @"^[1-9]\d*$"; 14 Regex regex = new Regex(pattern); 15 if (regex.IsMatch(str)) 16 return true; 17 else 18 return false; 19 } 20 }
我们就可以这样写了:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Console.WriteLine("a329".IsInt()); 6 7 Console.ReadKey(); 8 } 9 }
1 Console.WriteLine("a329".IsInt());
上边的这句代码编译后就等价于:
1 StringExtension.IsInt("a329");
当调用扩展方法IsInt()时,会先去找string类中是否存在这个方法,如果存在,则调用string类中的实例方法,如果不存在就去当前程序的扩展方法表里去找。
我们以string类型中的扩展方法Where()为例;其实扩展方法Where()并不是在string类中定义的,而是在Enumerable类中定义的,并在Enumerable类中将Where()这个扩展方法添加到了接口IEnumerable<T>中,又因为string类型实现了接口IEnumerable<T>,所以string就存在了Where()这个扩展方法。
注意:
- 定义扩展方法的类必须是静态类,扩展方法也必须是静态的
- 扩展方法第一个参数必须用this关键字修饰
- 如果类中存在实例方法,则优先调用实例方法,如果不存在实例方法,则调用扩展方法
- 当扩展方法在其他程序集中时,需要先添加引用,然后添加命名空间
- 可以让空引用调用扩展方法,但是前提是扩展方法中没有使用传入的实例对象,否则会报空指针错误
以上是关于扩展方法的主要内容,如果未能解决你的问题,请参考以下文章