代码改变世界

C#基础:通过一个实例来学习IFormattable接口,扩展方法

2013-04-19 18:30  海豚座  阅读(2206)  评论(0编辑  收藏  举报

    本实例中,定义了类型Student。Racer定义了几个属性和一个重载的ToString()方法,该方法以字符串格式显示学生信息。这个类实现了IFormattable接口,以支持格式字符串的不同变体。

    Student类声明如下:

    class Student:IFormattable
    {
        public string Name { get; set; }//姓名
        public string Age { get; set; }//年龄
        public string Address { get; set; }//地址
        public string StuNum { get; set; }//学号
        /// <summary>
        /// People构造函数,给学生实体赋值
        /// </summary>
        public Student(string name, string age, string address, string stuNum)
        {
            this.Name = name;
            this.Age = age;
            this.Address = address;
            this.StuNum = stuNum;
        }
        /// <summary>
        /// 实现IFormattable接口,格式化输出学生信息
        /// </summary>
        public string ToString(string format, IFormatProvider formatProvider)
        {
            switch (format)
            {
                //只输出姓名
                case "N": return "姓名"+Name;
                //输出学生全部信息
                case "F": return String.Format("姓名:{0}  年龄:{1}  学号:{2}  地址:{3}", Name, Age, StuNum, Address);
                //信息格式化失败,抛出异常
                default: throw new FormatException("信息格式化失败");
            }
        }
        //重载ToString方法,化简格式化输出的传入参数
        public string ToString(string format)
        {
            return ToString(format, null);
        }
    }

    扩展方法可以将方法写入最初没有提供该方法的类中。还可以把方法添加到实现某个特定接口的任何类中,这样多个类就可以使用相同的实现代码。

    例如,String类是密封的,所以我们不能继承这个类,我们可以通过扩展给String类添加方法tostring(),如下所示

public static class StringExtension
{
    public static void tostring(this string s)
    {
           Console.WriteLine("Extension output: {0}",s);
    }
}

    如上面的代码所示,扩展方法在静态类中声明,定义为一个静态方法,其中第一个参数定义了它扩展的类型。tostring()方法扩展了String类,因为它的第一个参数定义为String类型。为了区分扩展方法和一般的静态方法,扩展方法还需要对第一个参数使用this关键字。

    下面就可以使用String类型的扩展方法tostring()了,如下所示:

string s="Hello World! ";
s.tostring();

    结果在控制台显示的信息是:Extension output: Hello World!

    下面看看本实例中,获取学生信息GetInfomation这个类的定义

    static class GetInfomation
    {
        //初始化一个学生信息列表
        public static List<Student> stu;
        /// <summary>
        /// 给学生列表赋值
        /// </summary>
        /// <returns></returns>
        public static IList<Student> getStudent()
        {
            if (stu == null)
            {
                stu = new List<Student>();
                stu.Add(new Student("小吕", "23", "中国成都", "2940610410"));
                stu.Add(new Student("小方", "24", "中国浙江", "2940610411"));
                stu.Add(new Student("小范", "22", "中国成都", "2940610412"));
                stu.Add(new Student("小龚", "23", "中国遵义", "2940610413"));
                stu.Add(new Student("小秦", "24", "中国成都", "2940610624"));
            }
            return stu;
        }
        /// <summary>
        ///扩展方法,返回地址在成都的同学
        /// </summary>
        /// <param name="P"></param>
        /// <returns></returns>
        public static IEnumerable<Student> chengduStudent(this IList<Student> P)
        {
            //Linq查询,获取P列表中在成都的同学的信息
            var query = P.Where(p => p.Address == "中国成都").OrderByDescending(p => p.StuNum).Select(p => p);
            return query;
        }
        /// <summary>
        /// 扩展方法,返回年龄为23的同学
        /// </summary>
        /// <param name="P"></param>
        /// <returns></returns>
        public static IEnumerable<Student> ageStident(this IList<Student> P)
        {
            var query = P.Where(p => p.Age == "23").OrderByDescending(p => p.StuNum).Select(p => p);
            return query;
        }
    }

    最后,主函数调用这些方法的实例如下所示:

    class Program
    {
        static void Main(string[] args)
        {
            //获取学生信息列表
            var Result = GetInfomation.getStudent();
            //调用Linq查询扩展方法获取在成都的学生列表
            IEnumerable<Student> chengdu_stu=Result.chengduStudent();
            Console.WriteLine("地址在成都的学生信息列表:");
            foreach (Student p in chengdu_stu)
            {
                Console.WriteLine(p.ToString("F"));
            }
            Console.WriteLine("--------------------------------------------");
            Console.WriteLine("年龄为23岁的学生信息列表:");
            //调用扩展方法获取年龄等于23的学生信息
            IEnumerable<Student> age_stu = Result.ageStident();
            foreach (Student s in age_stu)
            {
                Console.WriteLine(s.ToString("F"));
            }
        }
    }

 

    输出结果: