• Posts - 33
• Stories - 0

【转】五、谈扩展方法的理解

# 为什么要用扩展方法

public 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
{
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;
}

# 扩展方法到底是什么

 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);

# 扩展方法可以做些什么

• 把已有的静态方法转成扩展方法：如：
public static bool IsNullOrEmpty(this string str)
{
return string.IsNullOrEmpty(str);
}

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

感觉相比期静态方法调用要优雅，更接近我们的自然语言。

•  可以编写很多的帮助类，如（以string为例）：
/// <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

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")}
};

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))
}
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);
}

 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#代码：

1. 第一个参数是要扩展或者要操作的类型,这称为"被扩展的类型"
2. 为了指定扩展方法,要在被扩展的类型名称前面附加this修饰符
3. 要将方法作为一个扩展方法来访问,要用using指令导入扩展类型的命名空间,或者使扩展类型和调用代码在同一个命名空间中.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
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);
}
}
}

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))
}
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

posted on 2018-01-11 11:24 RYouhoo 阅读(...) 评论(...) 编辑 收藏