.NET 扩展方法

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

看完上面的解释,有点摸不着头脑,我们在具体演示一下:

例子一:扩展Student类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace efdemo6
{
    class Program
    {
        static void Main(string[] args)
        {
            Student st = new Student()
            {
                StudentName = "张三",
                Score = 100, 
                Birthday = DateTime.Parse("1990-1-1")
            };
            st.ShowStudent();//调用 扩展方法  
        }
    }
    //扩展学生类的功能
    public static class ExStudent
    {
        //打印学生信息
        public static void ShowStudent(this Student st)
        {
            Console.WriteLine("姓名:"+st.StudentName+" 分数:"+st.Score+" 生日:"+st.Birthday.ToString());
        }
    }
}

说明:我们为学生类添加一个功能,打印学生信息 ShowStudent。

注意:1.扩展方法只能定义在 非泛型的静态类中,使用 static修饰,参数使用this关键字 修饰要扩展的类,此处为Student类扩展方法, this Student st

执行结果:

 

如图:扩展方法的图标带有向下的箭头,且被标注为:扩展。

 

例子二 扩展List<T>泛型类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace efdemo6
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> list = new List<Student> { 
                new Student()
                {
                    StudentName = "张三",
                    Score = 100,
                    Birthday = DateTime.Parse("1990-1-1")
                },
                new Student()
                {
                    StudentName = "李四",
                    Score = 80,
                    Birthday = DateTime.Parse("1990-1-1")
                }
            };

            Console.WriteLine("===排序前===");
            foreach (var v in list)
            {
                Console.WriteLine(v.StudentName + " " + v.Score);
            }
            list.OrderBy();
            Console.WriteLine("===排序后===");
            foreach (var v in list)
            {
                Console.WriteLine(v.StudentName + " " + v.Score);
            }
        }
    }
    //扩展学生类的功能
    public static class ExStudent
    {
        //扩展集合List 打印所有学生信息
        public static void OrderBy(this List<Student> list)
        {

            list.Sort(new MyCompare());
        }

        class MyCompare : IComparer<Student>
        {
            //比较学生的分数
            public int Compare(Student st1, Student st2)
            {
                if (st1.Score > st2.Score) return 1;  
                if (st1.Score == st2.Score) return 0; 
                return -1;
            }
        }
    }
}

执行结果:

说明:此处定义了2个学生对象,张三 100分 李四 80分 ,并封装在List<Student>集合中,现在扩展一个OrderBy方法,按照学生分数排序。list.Sort() 方法传递一个 实现了IComparer<T>接口的实现类对象,并实现里面的Compare方法。

按F2查看Sort方法源代码:

可以看到,List<T>还有另一个sort方法,传递的是一个委托。

所以我们可以像下面这样写:

    //扩展学生类的功能
    public static class ExStudent
    {
        public static void OrderBy(this List<Student> list)
        {

            list.Sort((x, y) =>
            {
                if (x.Score > y.Score) return 1;
                if (x.Score == y.Score) return 0;
                return -1;
            });
        }
    }

传递一个lamba表达式,运行结果相同。

posted @ 2016-08-10 14:12  思如雨  阅读(2411)  评论(0编辑  收藏  举报