C#扩展方法

转载自:c# 扩展方法详解
扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。 扩展方法当然不能破坏面向对象封装的概念,所以只能是访问所扩展类的public成员。
扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
C#扩展方法第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。
扩展方法的目的就是为一个现有类型添加一个方法,现有类型既可以是int,string等数据类型,也可以是自定义的数据类型。
为数据类型的添加一个方法的理解:一般来说,int数据类型有个Tostring的方法,就是把int 数据转换为字符串的类型,比如现在我们想在转换成字符串的时候还添加一点东西,比如增加一个字符 a .那么之前的Tostring就不好使了,因为它只是它我们的int数据转换为string类型的,却并不能添加一个字母 a.所以这就要用到所谓的扩展方法了。
首先我们看一个给现有的类型增加一个扩展方法。
我们想给string 类型增加一个Add方法,该方法的作用是给字符串增加一个字母a.

实例1:

       //必须是静态类才可以添加扩展方法  
       Static class Program  
       {  
        static void Main(string[] args)  
        {  
            string str = "quzijing";  
        //注意调用扩展方法,必须用对象来调用   
            string Newstr = str.Add();  
            Console.WriteLine(Newstr);  
            Console.ReadKey();  
        }  
        //声明扩展方法  
        //扩展方法必须是静态的,Add有三个参数  
        //this 必须有,string表示我要扩展的类型,stringName表示对象名  
        //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,//再增加一个变量即可  
        public static  string  Add(this string stringName)  
        {  
            return stringName+"a";  
        }  
}

我们再来尝试给我们自定义的类型增加一个扩展方法,并增加一个传递的参数。

实例2:

首先我们声明一个Student类,它包含了两个方法StuInfo,getStuInfo.实例代码如下:

public class Student  
{  
    public string StuInfo()  
    {  
        return "学生基本信息";  
    }  
    public  string getStuInfo(string stuName, string stuNum)  
    {  
   return string.Format("学生信息:\n" + "姓名:{0} \n" + "学号:{1}", stuName, stuNum);  
    }  
 }

之后我们再声明一个名为ExtensionStudentInfo的静态类,注意必须为静态
这个类的作用就是包含一些我们想要扩展的方法,在此我们声明两个Student类型的扩展方法,Student类型为我们自定义的类型。示例代码如下:

public static class ExtensionStudentInfo  
{  
    //声明扩展方法  
    //要扩展的方法必须是静态的方法,Add有三个参数  
    //this 必须有,string表示我要扩展的类型,stringName表示对象名  
    //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,再增加一个变量即可  
    public static string ExtensionStuInfo(this Student stuName)  
    {  
        return stuName.StuInfo();  
    }  
    //声明扩展方法  
    //要扩展的方法必须是静态的方法,Add有三个参数  
    //this 必须有,string表示我要扩展的类型,stringName表示对象名  
    //三个参数this和扩展的类型必不可少,对象名可以自己随意取如果需要传递参数,在此我们增加了两个string类型的参数  
    public static string ExtensionGetStuInfo(this Student student, string stuname, string stunum)  
    {  
        return student.getStuInfo(stuname, stunum)+"\n读取完毕";  
    }  
}

以上的工作做完之后便可以使用我们的扩展方法了,注意必须要用对象来调用扩展方法。

        static void Main(string[] args)  
        {  
            Student newstudent = new Student();  
//要使用对象调用我们的扩展方法  
            string stuinfo = newstudent.ExtensionStuInfo();  
            Console.WriteLine(stuinfo);  
//要使用对象调用我们的扩展方法  
string stuinformation = newstudent.ExtensionGetStuInfo("quzijing", "20081766");  
            Console.WriteLine(stuinformation);  
            Console.ReadKey();  
        }

实例3

(1)、扩展方法

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Text.RegularExpressions;  
//声明扩展方法的步骤:类必须是static,方法是static,    
//第一个参数是被扩展的对象,前面标注this。    
//使用扩展方法的时候必须保证扩展方法类已经在当前代码中using    
namespace 扩展方法    
{    
    //扩展方法必须是静态的   
    public static class StringHelper  
    {  
        //扩展方法必须是静态的,第一个参数必须加上this  
        public static bool IsEmail(this string _input)  
        {  
            return Regex.IsMatch(_input, @"^\\w+@\\w+\\.\\w+$");  
        }  
        //带多个参数的扩展方法  
        //在原始字符串前后加上指定的字符  
        public static string Quot(this string _input, string _quot)  
        {
            return _quot + _input + _quot; 
        } 
    }  
}  

(2)、使用方法

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
namespace 扩展方法  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            string _myEmail = "[email protected]";  
            //这里就可以直接使用string类的扩展方法IsEmail了  
            Console.WriteLine(_myEmail.IsEmail());  
            //调用接收参数的扩展方法  
            Console.WriteLine(_myEmail.Quot("!"));  
            Console.ReadLine();  
        }  
    }  
}  

总结:

扩展方法有就近原则,也就是如果在你的程序里有两个一模一样的扩展方法,一个和你的使用类是处于同一命名空间里,另外一个处于别的命名空间里,这个时候会优先使用同一命名空间里的扩展方法,也就是说“血缘关系”越近,越被青睐。

很多人看到扩展方法也许眼里冒出金光,以后在设计的时候不管三七二十一,反正可以扩展。还有一些人会对类任意扩展,将以前一些作为”Helper”的方法统统使用扩展方法代替,注意的是扩展方法有“污染性”,所以我觉得在扩展的时候还是想想,是不是值得这样扩展。

在扩展的时候也不要对比较高层的类进行扩展,像我上面对object的扩展我觉得就是不可取的,object是所有类的基类,一经扩展,所有的类都被“污染”了。

你可能感兴趣的:(C#扩展方法)