扩展方法

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关键字修饰
  • 如果类中存在实例方法,则优先调用实例方法,如果不存在实例方法,则调用扩展方法
  • 当扩展方法在其他程序集中时,需要先添加引用,然后添加命名空间
  • 可以让空引用调用扩展方法,但是前提是扩展方法中没有使用传入的实例对象,否则会报空指针错误

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

VS中添加自定义代码片段——偷懒小技巧

有人可以在快速数组中给出“如果不存在则追加”方法的片段吗?

如何在扩展另一个文件的 django 模板中使用带有动态内容的 html 块片段?

从父片段调用方法

调用 replace() 方法后片段闪烁/闪烁

VS Code配置snippets代码片段快速生成html模板,提高前端编写效率