谈扩张方法的了然,谈扩展方法的精晓

【转】五、谈扩大方法的精通

为啥要用扩大方法

在说怎么是扩展方法从前我们先来说说为啥要用扩大方法。

第一我们定义一个 Person 类:

public class Person
{
    /// <summary>
    /// 出生日期
    /// </summary>
    public DateTime BirthTime { get; set; }
    /// <summary>
    /// 死亡日期
    /// </summary>
    public DateTime? DeathTime { get; set; }
    //、、、、、、
}

投入这一个类来自第三方的dll引用,且现在我们需要丰富一个措施 GetAge 获取年龄。你也许会想到自己定一个子类继承:

public class MyPerson : Person
{
    public int GetAge()
    {
        if (DeathTime.HasValue)
            return (DeathTime.Value - BirthTime).Days / 365;
        else
            return (DateTime.Now - BirthTime).Days / 365;
    }
}

科学,这样可以实现大家的需要。可是实现增产的章程就去继承真的是最合适的吧(暂且不说)? 假若下边定义的密封类呢? public sealed class
Person ,这几个时候是不可以持续的,大家只可以另想办法。

随意写个静态类:

public static class ExtensionClass
{
    public static int GetAge(Person person)
    {
        if (person.DeathTime.HasValue)
            return (person.DeathTime.Value - person.BirthTime).Days / 365;
        else
            return (DateTime.Now - person.BirthTime).Days / 365;
    }

接下来调用  age =
ExtensionClass.GetAge(p); ,是的看似天经地义。不过这和我们说的恢弘方法有怎么样关联吧?下边就是见证奇迹的时候了。

图片 1

任何的其余地方都不变,唯一变化的是在参数前边加里(Gary)this关键字。对,是的,仅仅如此它就成为了我们前几天要讲的恢弘方法。

调用如:  var age =
p.GetAge(); 比较下面的 age =
ExtensionClass.GetAge(p); 更简单明了。

这里大家说的是在急需扩展密封类的不二法门时,我们可以动用到扩展方法。还有一种境况就是,在急需扩展接口的时候时候大家更加需要。比如,需要增加IList的排序。我们依然写个增加方法,要么是延续实现接口(会强制要求落实接口下的享有办法)。我想你心里早已有了答案选用哪个种类办法。

干什么要用扩大方法

在说怎样是扩大方法从前我们先来说说为何要用扩张方法。

先是我们定义一个 Person 类:

public class Person
{
    /// <summary>
    /// 出生日期
    /// </summary>
    public DateTime BirthTime { get; set; }
    /// <summary>
    /// 死亡日期
    /// </summary>
    public DateTime? DeathTime { get; set; }
    //、、、、、、
}

进入那一个类来自第三方的dll引用,且现在我们需要加上一个艺术 GetAge 获取年龄。你或许会想到自己定一个子类继承:

public class MyPerson : Person
{
    public int GetAge()
    {
        if (DeathTime.HasValue)
            return (DeathTime.Value - BirthTime).Days / 365;
        else
            return (DateTime.Now - BirthTime).Days / 365;
    }
}

毋庸置疑,这样可以兑现大家的要求。不过实现新增的方法就去继承真的是最合适的啊(暂且不说)? 假如下面定义的密封类呢? public sealed class
Person ,那些时候是不可能继承的,我们只好另想办法。

随意写个静态类:

public static class ExtensionClass
{
    public static int GetAge(Person person)
    {
        if (person.DeathTime.HasValue)
            return (person.DeathTime.Value - person.BirthTime).Days / 365;
        else
            return (DateTime.Now - person.BirthTime).Days / 365;
    }

下一场调用  age =
ExtensionClass.GetAge(p); ,是的看似天经地义。然而这和大家说的恢弘方法有如何关联吗?上边就是见证奇迹的时候了。

图片 2

任何的其他地点都不变,唯一变化的是在参数前边加里(加里(Gary))this关键字。对,是的,仅仅如此它就改成了俺们明日要讲的恢宏方法。

调用如:  var age =
p.GetAge(); 比较下面的 age =
ExtensionClass.GetAge(p); 更简单明了。

这里我们说的是在需要扩展密封类的主意时,大家得以应用到增加方法。还有一种状态就是,在需要扩张接口的时候时候大家进一步急需。比如,需要扩大IList的排序。我们如故写个扩展方法,要么是后续实现接口(会强制要求贯彻接口下的具备办法)。我想你心里已经有了答案采取哪类方法。

扩展方法到底是什么样

俺们看出下边使用的增加方法,有没有感觉很神奇。仅仅多添加了一个this关键字就径直能够算作扩张方法运用了。这扩张方法到底是怎么样东东,看了下边代码好像和静态方法有着说不清道不明的涉嫌。上边我们后续分析:

各自定义一个静态方法和一个恢弘方法

 public static class ExtensionClass
 {
     public static int GetAge2(Person person)
     {
         if (person.DeathTime.HasValue)
             return (person.DeathTime.Value - person.BirthTime).Days / 365;
         else
             return (DateTime.Now - person.BirthTime).Days / 365;
     }

     public static int GetAge(this Person person)
     {
         if (person.DeathTime.HasValue)
             return (person.DeathTime.Value - person.BirthTime).Days / 365;
         else
             return (DateTime.Now - person.BirthTime).Days / 365;
     }

分级调用:

var p = new Person() { BirthTime = DateTime.Parse("1990-07-19") };
var age = p.GetAge();
age = ExtensionClass.GetAge2(p);

编译后的IL代码:

图片 3

俺们看出反编译成IL之后发现两者并无不同。所以,我晓得成(扩张方法本质上就是静态方法,之所以出现恢弘方法是C#以其余一种样式展现静态方法而已。唯有有何妙用下面会连续上课)。且 图片 4编译后图片 5一致带上了静态类名。

增添方法到底是咋样

大家看来下面使用的增添方法,有没有痛感很神奇。仅仅多添加了一个this关键字就径直可以算作扩大方法运用了。这扩张方法到底是什么东东,看了地点代码好像和静态方法有着说不清道不明的关联。下面我们继承分析:

分级定义一个静态方法和一个扩张方法

 public static class ExtensionClass
 {
     public static int GetAge2(Person person)
     {
         if (person.DeathTime.HasValue)
             return (person.DeathTime.Value - person.BirthTime).Days / 365;
         else
             return (DateTime.Now - person.BirthTime).Days / 365;
     }

     public static int GetAge(this Person person)
     {
         if (person.DeathTime.HasValue)
             return (person.DeathTime.Value - person.BirthTime).Days / 365;
         else
             return (DateTime.Now - person.BirthTime).Days / 365;
     }

个别调用:

var p = new Person() { BirthTime = DateTime.Parse("1990-07-19") };
var age = p.GetAge();
age = ExtensionClass.GetAge2(p);

编译后的IL代码:

图片 6

我们看看反编译成IL之后察觉互相并无不同。所以,我领悟成(扩张方法本质上就是静态方法,之所以出现扩充方法是C#以其余一种样式呈现静态方法而已。只有有何妙用上面会持续教师)。且 图片 7编译后图片 8无异于带上了静态类名。

扩充方法可以做些什么

  • 把已有些静态方法转成扩展方法:如:

    public static bool IsNullOrEmpty(this string str)
    {

    return string.IsNullOrEmpty(str);
    

    }

调用: 

string str = null;
var isNull = str.IsNullOrEmpty();

 感觉相相比期静态方法调用要优雅,更类似大家的自然语言。

  •  可以编制很多的帮衬类,如(以string为例):

图片 9图片 10

/// <summary>
        /// 转DateTime 
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static DateTime? MyToDateTime(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return null;
            else
                return DateTime.Parse(str);
        }

        /// <summary>
        /// 转double
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static double MyToDouble(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return -1;
            else
                return double.Parse(str);
        }

        /// <summary>
        /// 转int
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int MyToInt(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return -1;
            else
                return int.Parse(str);
        }

        /// <summary>
        /// 指示指定的字符串是 null 还是 System.String.Empty 字符串。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// 如果字符串为null,则返回空字符串。(否则返回原字符串)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetValueOrEmpty(this string str)
        {
            if (str.IsNullOrEmpty())
                return string.Empty;
            return str;
        }

View Code

地方装有的都只是扩充方法的增大用处,增添方法确实的威力是为Linq服务的(紧要反映于IEnumerable和IQueryable),实现链式编程。上边我们协调来贯彻所谓的链式编程:

初始化 Person 集合。

List<Person> persons = new List<Person>() 
{
     new Person(){ BirthTime=DateTime.Parse("1990-01-19")},
     new Person(){ BirthTime=DateTime.Parse("1993-04-17")},
     new Person(){ BirthTime=DateTime.Parse("1992-07-19"), DeathTime=DateTime.Parse("2010-08-18")},
     new Person(){ BirthTime=DateTime.Parse("1990-03-14")},
     new Person(){ BirthTime=DateTime.Parse("1991-08-15")},
     new Person(){ BirthTime=DateTime.Parse("1993-07-29")},
     new Person(){ BirthTime=DateTime.Parse("1991-06-19")}
};

要求:1.询问活人。2.按出生日期排序

public static class ExtensionClass
    {
        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyWhere<T>(this IList<T> list, Func<T, bool> func)
        {
            List<T> newList = new List<T>();
            foreach (var item in list)
            {
                if (func(item))
                    newList.Add(item);
            }
            return newList;
        }

        /// <summary>
        /// 升序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderBy<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = i + 1; j < list.Count(); j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks > 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 降序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderByDescending<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = 1; j < list.Count() - i; j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks < 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
    }

调用:(这里只有为了演示,所以并非谈论实现是否创造、算法是否连忙。)

var newPersons = persons.MyWhere(t => t.DeathTime == null).MyOrderByDescending(t => t.BirthTime);
foreach (var item in newPersons)
{
    Console.WriteLine(item.BirthTime);
}

就是这么简约的兑现了所谓的函数式编程。结果图如下:

图片 11

诸如此类一句代码搞定所有逻辑,像自然语言般的流畅。其实.net为IEnumerable实现了这么的恢宏,如:

图片 12

推行社团和下边一模一样。

 

实质上扩张方法也可以算作静态方法来行使:

 var p1 = ExtensionClass.MyWhere(persons, t => t.DeathTime == null);
 var p2 = ExtensionClass.MyOrderByDescending(p1, t => t.BirthTime);
 var p3 = ExtensionClass.MyOrderBy(p2, t => t.BirthTime);

(不信?继续看,有图有实质)

 

C#代码:

 图片 13

反编译C#的代码:(你是不是见到了,编译后从来就是采取的增加方法的形式。)

图片 14

反编译的IL代码:

图片 15

尽管如此编译后的代码是一模一样的,可是做为程序员的我们更欣赏哪个种类办法呢?图片 16

 

总结:

咱俩在对增添方法的怎么使用疑惑或者忘记了平整的时候,我们不用去查找资料说:

  1. 首先个参数是要壮大或者要操作的品类,这称为”被扩大的品类”
  2. 为了指定扩充方法,要在被扩充的项目名称前边附加this修饰符
  3. 要将艺术作为一个扩充方法来拜访,要用using指令导入扩充类型的命名空间,或者使扩展项目和调用代码在同一个命名空间中.

大家只需记住,当您不清楚怎么编写或使用扩充方法时,你先把它正是静态方法编写或应用。即便可行,一般都足以转成增添方法的样式。

 

成套代码:

图片 17图片 18

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.Utilities;
using System.Diagnostics.CodeAnalysis;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;

namespace test
{


    class Program
    {
        static void Main(string[] args)
        {
            /*             
             * 1.工具类
             * 2.链式编程
             */
            string str = null;
            var isNull = str.IsNullOrEmpty();

            var p = new Person() { BirthTime = DateTime.Parse("1990-07-19") };
            var age = p.GetAge();
            age = ExtensionClass.GetAge2(p);

            List<Person> persons = new List<Person>() 
            {
                 new Person(){ BirthTime=DateTime.Parse("1990-01-19")},
                 new Person(){ BirthTime=DateTime.Parse("1993-04-17")},
                 new Person(){ BirthTime=DateTime.Parse("1992-07-19"), DeathTime=DateTime.Parse("2010-08-18")},
                 new Person(){ BirthTime=DateTime.Parse("1990-03-14")},
                 new Person(){ BirthTime=DateTime.Parse("1991-08-15")},
                 new Person(){ BirthTime=DateTime.Parse("1993-07-29")},
                 new Person(){ BirthTime=DateTime.Parse("1991-06-19")}
            };

            var newPersons = persons.MyWhere(t => t.DeathTime == null).MyOrderByDescending(t => t.BirthTime);


            var p1 = ExtensionClass.MyWhere(persons, t => t.DeathTime == null);
            var p2 = ExtensionClass.MyOrderByDescending(p1, t => t.BirthTime);
            var p3 = ExtensionClass.MyOrderBy(p2, t => t.BirthTime);

            foreach (var item in newPersons)
            {
                Console.WriteLine(item.BirthTime);
            }
            Console.ReadKey();
        }
    }

    public sealed class Person
    {
        /// <summary>
        /// 出生日期
        /// </summary>
        public DateTime BirthTime { get; set; }
        /// <summary>
        /// 死亡日期
        /// </summary>
        public DateTime? DeathTime { get; set; }
    }

    //public class MyPerson : Person
    //{
    //    public int GetAge()
    //    {
    //        if (DeathTime.HasValue)
    //            return (DeathTime.Value - BirthTime).Days / 365;
    //        else
    //            return (DateTime.Now - BirthTime).Days / 365;
    //    }
    //}
    public static class ExtensionClass
    {
        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyWhere<T>(this IList<T> list, Func<T, bool> func)
        {
            List<T> newList = new List<T>();
            foreach (var item in list)
            {
                if (func(item))
                    newList.Add(item);
            }
            return newList;
        }

        /// <summary>
        /// 升序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderBy<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = i + 1; j < list.Count(); j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks > 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 降序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderByDescending<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = 1; j < list.Count() - i; j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks < 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }

        public static int GetAge2(Person person)
        {
            if (person.DeathTime.HasValue)
                return (person.DeathTime.Value - person.BirthTime).Days / 365;
            else
                return (DateTime.Now - person.BirthTime).Days / 365;
        }

        public static int GetAge(this Person person)
        {
            if (person.DeathTime.HasValue)
                return (person.DeathTime.Value - person.BirthTime).Days / 365;
            else
                return (DateTime.Now - person.BirthTime).Days / 365;
        }

        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }
    } 
}

View Code

 

正文以联合至《C#基础知识巩固系列

壮大方法可以做些什么

  • 把已部分静态方法转成扩大方法:如:

    public static bool IsNullOrEmpty(this string str)
    {

    return string.IsNullOrEmpty(str);
    

    }

调用: 

string str = null;
var isNull = str.IsNullOrEmpty();

 感觉相比期静态方法调用要优雅,更仿佛我们的自然语言。

  •  可以编写很多的支援类,如(以string为例):

图片 19图片 20

/// <summary>
        /// 转DateTime 
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static DateTime? MyToDateTime(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return null;
            else
                return DateTime.Parse(str);
        }

        /// <summary>
        /// 转double
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static double MyToDouble(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return -1;
            else
                return double.Parse(str);
        }

        /// <summary>
        /// 转int
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int MyToInt(this string str)
        {
            if (string.IsNullOrEmpty(str))
                return -1;
            else
                return int.Parse(str);
        }

        /// <summary>
        /// 指示指定的字符串是 null 还是 System.String.Empty 字符串。
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        /// <summary>
        /// 如果字符串为null,则返回空字符串。(否则返回原字符串)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetValueOrEmpty(this string str)
        {
            if (str.IsNullOrEmpty())
                return string.Empty;
            return str;
        }

View Code

下边装有的都只是扩展方法的叠加用处,扩大方法真的的威力是为Linq服务的(紧要显示于IEnumerable和IQueryable),实现链式编程。上边咱们友好来促成所谓的链式编程:

初始化 Person 集合。

List<Person> persons = new List<Person>() 
{
     new Person(){ BirthTime=DateTime.Parse("1990-01-19")},
     new Person(){ BirthTime=DateTime.Parse("1993-04-17")},
     new Person(){ BirthTime=DateTime.Parse("1992-07-19"), DeathTime=DateTime.Parse("2010-08-18")},
     new Person(){ BirthTime=DateTime.Parse("1990-03-14")},
     new Person(){ BirthTime=DateTime.Parse("1991-08-15")},
     new Person(){ BirthTime=DateTime.Parse("1993-07-29")},
     new Person(){ BirthTime=DateTime.Parse("1991-06-19")}
};

要求:1.查询活人。2.按出生日期排序

public static class ExtensionClass
    {
        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyWhere<T>(this IList<T> list, Func<T, bool> func)
        {
            List<T> newList = new List<T>();
            foreach (var item in list)
            {
                if (func(item))
                    newList.Add(item);
            }
            return newList;
        }

        /// <summary>
        /// 升序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderBy<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = i + 1; j < list.Count(); j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks > 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 降序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderByDescending<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = 1; j < list.Count() - i; j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks < 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
    }

调用:(这里唯有为了演示,所以不用谈论实现是否制造、算法是否急忙。)

var newPersons = persons.MyWhere(t => t.DeathTime == null).MyOrderByDescending(t => t.BirthTime);
foreach (var item in newPersons)
{
    Console.WriteLine(item.BirthTime);
}

就是这样简单的兑现了所谓的函数式编程。结果图如下:

图片 21

如此这般一句代码搞定所有逻辑,像自然语言般的流畅。其实.net为IEnumerable实现了这么的壮大,如:

图片 22

执行协会和下边一模一样。

 

实质上扩大方法也可以算作静态方法来行使:

 var p1 = ExtensionClass.MyWhere(persons, t => t.DeathTime == null);
 var p2 = ExtensionClass.MyOrderByDescending(p1, t => t.BirthTime);
 var p3 = ExtensionClass.MyOrderBy(p2, t => t.BirthTime);

(不信?继续看,有图有实质)

 

C#代码:

 图片 23

反编译C#的代码:(你是不是来看了,编译后从来就是运用的扩张方法的花样。)

图片 24

反编译的IL代码:

图片 25

即使编译后的代码是平等的,可是做为程序员的大家更爱好哪类方法吗?图片 26

 

总结:

俺们在对扩张方法的怎么接纳疑惑或者忘记了平整的时候,大家不用去查找资料说:

  1. 第一个参数是要扩张或者要操作的序列,这叫做”被增添的连串”
  2. 为了指定扩张方法,要在被扩大的门类名称前边附加this修饰符
  3. 要将艺术作为一个扩张方法来拜访,要用using指令导入增加项目标命名空间,或者使扩大类型和调用代码在同一个命名空间中.

咱俩只需记住,当你不知晓怎么编写或拔取扩大方法时,你先把它当成静态方法编写或使用。倘若可行,一般都得以转成扩张方法的样式。

 

一切代码:

图片 27图片 28

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.Utilities;
using System.Diagnostics.CodeAnalysis;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;

namespace test
{


    class Program
    {
        static void Main(string[] args)
        {
            /*             
             * 1.工具类
             * 2.链式编程
             */
            string str = null;
            var isNull = str.IsNullOrEmpty();

            var p = new Person() { BirthTime = DateTime.Parse("1990-07-19") };
            var age = p.GetAge();
            age = ExtensionClass.GetAge2(p);

            List<Person> persons = new List<Person>() 
            {
                 new Person(){ BirthTime=DateTime.Parse("1990-01-19")},
                 new Person(){ BirthTime=DateTime.Parse("1993-04-17")},
                 new Person(){ BirthTime=DateTime.Parse("1992-07-19"), DeathTime=DateTime.Parse("2010-08-18")},
                 new Person(){ BirthTime=DateTime.Parse("1990-03-14")},
                 new Person(){ BirthTime=DateTime.Parse("1991-08-15")},
                 new Person(){ BirthTime=DateTime.Parse("1993-07-29")},
                 new Person(){ BirthTime=DateTime.Parse("1991-06-19")}
            };

            var newPersons = persons.MyWhere(t => t.DeathTime == null).MyOrderByDescending(t => t.BirthTime);


            var p1 = ExtensionClass.MyWhere(persons, t => t.DeathTime == null);
            var p2 = ExtensionClass.MyOrderByDescending(p1, t => t.BirthTime);
            var p3 = ExtensionClass.MyOrderBy(p2, t => t.BirthTime);

            foreach (var item in newPersons)
            {
                Console.WriteLine(item.BirthTime);
            }
            Console.ReadKey();
        }
    }

    public sealed class Person
    {
        /// <summary>
        /// 出生日期
        /// </summary>
        public DateTime BirthTime { get; set; }
        /// <summary>
        /// 死亡日期
        /// </summary>
        public DateTime? DeathTime { get; set; }
    }

    //public class MyPerson : Person
    //{
    //    public int GetAge()
    //    {
    //        if (DeathTime.HasValue)
    //            return (DeathTime.Value - BirthTime).Days / 365;
    //        else
    //            return (DateTime.Now - BirthTime).Days / 365;
    //    }
    //}
    public static class ExtensionClass
    {
        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyWhere<T>(this IList<T> list, Func<T, bool> func)
        {
            List<T> newList = new List<T>();
            foreach (var item in list)
            {
                if (func(item))
                    newList.Add(item);
            }
            return newList;
        }

        /// <summary>
        /// 升序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderBy<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = i + 1; j < list.Count(); j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks > 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 降序排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static IList<T> MyOrderByDescending<T>(this IList<T> list, Func<T, DateTime> func)
        {
            if (list.Count() <= 1)
                return list;

            for (int i = 0; i < list.Count(); i++)
            {
                for (int j = 1; j < list.Count() - i; j++)
                {
                    var item1 = list[j - 1];
                    var item2 = list[j];
                    if ((func(item1) - func(item2)).Ticks < 0)
                    {
                        list[j - 1] = item2;
                        list[j] = item1;
                    }
                }
            }
            return list;
        }

        public static int GetAge2(Person person)
        {
            if (person.DeathTime.HasValue)
                return (person.DeathTime.Value - person.BirthTime).Days / 365;
            else
                return (DateTime.Now - person.BirthTime).Days / 365;
        }

        public static int GetAge(this Person person)
        {
            if (person.DeathTime.HasValue)
                return (person.DeathTime.Value - person.BirthTime).Days / 365;
            else
                return (DateTime.Now - person.BirthTime).Days / 365;
        }

        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }
    } 
}

View Code

 

本文以一头至《C#基础知识巩固系列

admin

网站地图xml地图