扩展方法

msdn是这样给扩展方法定义的:

扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异。

可能你在第一次看到的时候有点晕,下面就通过一个小的demo来讲解一下。

新建一个项目命名为:ExtensionMethods,项目结构如下图所示:

项目结构

首先讲解一下Employee,Employees,Salary类

Employee:Employee model有Name,Gender,Age,Salary属性,重载了object的ToSring()方法,用于返回Employee信息。

public sealed class Employee
    {
        public string Name { get; set; }

        public Gender Gender { get; set; }

        public int Age { get; set; }

        public Salary Salary { get; set; }

        public Employee(string name, Gender gender, int age, Salary salary)
        {
            this.Name = name;
            this.Gender = gender;
            this.Age = age;
            this.Salary = salary;
        }

        public override string ToString()
        {
            return string.Format("Name:{0} Gender:{1} Age:{2} Salary:{3}", Name, Gender.ToString(), Age.ToString(), Salary.GetSalary().ToString());
        }
    }

    public enum Gender
    {
        MALE,
        FORMALE
    }

Employees:一个Employee 的列表。

public class Employees
    {
        private IList<Employee> empleoyees = null;
        public Employees()
        {
            empleoyees = new List<Employee>();

            //initialize the sample data for test.
            initializeSampleData();
        }

        private void initializeSampleData()
        {
            if (empleoyees == null)
                empleoyees = new List<Employee>();

            var lastGender = Gender.MALE;
            for (int i = 0; i < 10; i++)
            {

                //add test data.
                lastGender = (lastGender == Gender.MALE ? Gender.FORMALE : Gender.MALE);
                empleoyees.Add(new Employee("employee:" + i.ToString(),
                    lastGender,
                    (i + 1) * 1000,
                    new Salary(new Random().Next(10000, 20000))));
            }
        }

        public IList<Employee> GetEmployees()
        {
            return empleoyees;
        }
    }

Salary:用于计算employee的salry.

 public class Salary
    {
        public float BaseSalary { get; set; }

        public Salary(float _baseSalary)
        {
            this.BaseSalary = _baseSalary;
        }

        public float GetSalary()
        {
            return BaseSalary;
        }
    }

如果我想得到一个Emploeyee的列表,只要调用Employees类的GetEmployees方法就可以了,像这样:

IList<Employee> employees = new Employees().GetEmployees();

那如果我想把列表中的内容输出出来,该怎么办呢?

你可以这样:

            IList<Employee> employees = new Employees().GetEmployees();
          

            for (int i = 0; i < employees.Count; i++)
            {
                Console.WriteLine(employees[i].ToString());
            }

如果你在别的地方也需要把内容输出该怎么办呢?复制还是把方法提出来?这时候还有一个更好的方法,那就是使用扩展方法,就是demo中的ExtensionEmployee,代码如下:

 public static class ExtensionEmployee
    {
        public static void DisplayEmployeesInfo(this List<Employee> employees)
        {
            if (employees == null)
                return;

            for (int i = 0; i < employees.Count; i++)
            {
                Console.WriteLine(employees[i].ToString());
            }
        }
    }

使用方法:

 List<Employee> employees = (List<Employee>)new Employees().GetEmployees();
 employees.DisplayEmployeesInfo();

签名方式:

扩展方法的语法点是类和方法的签名必须是pulic和static,扩展方法的第一个参数前加this修饰,用来指示要操作的数据对象,在本demo中就是employees变量,这样就可以像调用List<T>本身的方法一样使用它了,另外扩展方法还支持扩展接口,例如我把demo中扩展方法的签名改成:

public static void DisplayEmployeesInfo(this IList<Employee> employees)

这样的话,List<Employee>和IList<Employee>都可以直接使用这个扩展方法了。

扩展方法的工作方式:

在编译时,它首先会查找IList<T>类型,查看该类型是否定义了DisplayEmployeesInfo方法,如果找到了,会进行调用,如果没有找到,会在全局搜索所有的静态类,查找该静态类下面是否有一个名为DisplayEmployeesInfo的方法,并且该方法的第一个参数用this标记,且参数类型与IList<Employee>兼容,如果找到则进行调用。

你也许会问,如果自己定义的扩展方法名称在该类型中已经存在,并且方法签名也一样会怎么样呢?这时会优先使用类型原生的方法。

demo下载地址:http://yunpan.cn/QDv5CT2DxnDyj

 欢迎指正!

谢谢


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值