【笔记】【LINQ编程技术内幕】第三章 定义扩展方法和分布方法

1. 扩展方法及其使用规则

  • 使用扩展方法可以扩展密封类型,无需继承
  • 利用扩展方法可以避免出现失控的深度继承层次体系
  • 扩展方法是静态类中的静态方法
  • 扩展方法第一个参数的类型之前必须使用this修饰符;this指带将要被扩展的类型
  • 不支持扩展属性、事件和操作符
  • 相对于实例方法而言,扩展方法的可视性要差一些,而且限制也会多一些
  • 拓展方法是通过实例语法来调用的
  • 拓展方法的优先级比常规方法要低;因此,如果某个类有用一个同名方法的话,那么被调用的将会是实例方法
  • 扩展方法得到只能感知的支持
  • 泛型扩展方法是得到支持的,事实上,System.Linq命名空间中许多LINQ关键字就是通过这个而实现的
  • 扩展方法能在字面量上调用
  • 拓展方法可以用在密封类和内部类上,因为扩展方法自动支持装箱和拆箱
  • 拓展方法并不是真正的成员,因此只能在其中访问被扩展对象的公共成员
  • 拓展方法隐式使用ExtensionAttribute
class Program
{
	static void Main(string[] args)
	{
		var song = new { Artist = "Jussi Bjorling", Song = "Aida" };
		song.Dump();
	}
}

// 静态类
public static class Dumper
{
	// 静态方法
	public static void Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
			}
			catch
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
			}
		}
	}
}

2. 带返回值的扩展方法

class Program
{
	static void Main(string[] args)
	{
		var songs = new
		{
			Artist = "Green Day",
			Song = "Wake Me Up When September Ends"
		};

		Console.WriteLine(songs.Dump());
	}
}

public static class Dumper
{
	// 带返回值得扩展方法
	public static string Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		StringBuilder builder = new StringBuilder();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
			builder.AppendLine();
		}
		return builder.ToString();
	}
}

3. 带参数得扩展方法

static void Main(string[] args)
{
	var song = new
	{
		Artist = "Avril Lavigne",
		Song = "My Happy Ending"
	};

	song.Dump(Console.Out);
}



public static class Dumper
{
	public static void Dump(this Object o, TextWriter writer)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
			}
			catch
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
			}
		}
	}
}

4. 重载扩展方法

class Program
{
	static void Main(string[] args)
	{
		var songs = new[]
		{
		  new {Artist="Jussi Bjorling", Song="Aida"},
		  new {Artist="Sheryl Crow", Song="Steve McQueen"}
		};

		songs.Dump();
	}
}



public static class Dumper
{
	public static void Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
		}
	}

	public static void Dump(this IList list)
	{
		foreach (object o in list)
			o.Dump();
	}
}

5. 泛型扩展方法

class Program
{
	static void Main(string[] args)
	{
		// 连接字符串
		string connectionString = "Data Source=CASPAR;Initial Catalog=Northwind;Integrated Security=True";
		
		// 存储结果集合
		List<Order> orders = new List<Order>();

		// 数据库连接
		using (SqlConnection connection = new SqlConnection(connectionString))
		{
			// 执行查询
			SqlCommand command = new SqlCommand("SELECT * FROM ORDERS", connection);
			command.CommandType = CommandType.Text;
			connection.Open();
			SqlDataReader reader = command.ExecuteReader();

			// 读取查询结果
			while (reader.Read())
			{
				Order order = new Order();
				
				// 根据读取得结果初始化Order实例
				order.Read(reader);
				// 存储结果
				orders.Add(order);
			}
		}

		// 显示结果
		orders.Dump(Console.Out);
	}
}

/// <summary>Order类得扩展方法,用于读取指定得字段。EntityClass拓展方法根据值是否为空返回不同得值</summary>
public static class ReaderHelper
{
	public static void Read(this Order order, IDataReader reader)
	{
		order.OrderID = order.SafeRead(reader, "OrderID", -1);
		order.CustomerID = order.SafeRead(reader, "CustomerID", "");
	}

	public static T SafeRead<T>(this EntityClass entity,IDataReader reader, string fieldName, T defaultValue)
	{
		try
		{
			object o = reader[fieldName];
			if (o == null || o == System.DBNull.Value)
				return defaultValue;

			return (T)Convert.ChangeType(o, defaultValue.GetType());
		}
		catch
		{
			return defaultValue;
		}
	}
}

/// <summary>封装扩展方法得静态类,该类中得拓展方法用于显示信息</summary>
public static class Dumper
{
	public static void Dump(this Object o, TextWriter writer)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
		}
	}

	public static void Dump<T>(this IList<T> list, TextWriter writer)
	{
		foreach (object o in list)
			o.Dump(writer);
	}
}


/// <summary>空得实体类,用于演示泛型拓展方法</summary>
public class EntityClass { }

/// <summary>该类继承自实体类</summary>
public class Order : EntityClass
{
	public Order(){}
	public int OrderID {get;set;}
	public string CustomerID {get;set;}
}

6. 拓展方法是如何支持LINQ得

LIQN是一种语法糖,在底层调用的则是对应的拓展方法。

LIQN查询

var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };

var evens = from num in numbers where num % 2 == 0 select num;

foreach (var result in evens)
	Console.WriteLine(result);

拓展方法

var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };

var evens = numbers.Where(item => item % 2 == 0).Select(item=>item);

foreach (var result in evens)
	Console.WriteLine(result);

7. 分部方法

  • 分部方法要声明在分部类中
  • 分部方法要使用partial修饰符
  • 分部方法在声明时不能有方法体
  • 分部方法之呢个返回void
  • 分部方法可以时静态的,而且可以有参数和参数修饰符
  • 分部方法是私有的,不过不能再字面上使用访问修饰符;也就是说,你不能显示使用private关键字
  • 编译器忽略未使用的分部方法
class Program
{
	static void Main(string[] args)
	{
		// 复合类型初始化
		CustomerList customers = new CustomerList
			{
				new Customer{CustomerID=1, Name="Levi, Ray and Shoup"},
				new Customer{CustomerID=2, Name="General Dynamics Land Systems"},
				new Customer{CustomerID=3, Name="Microsoft"}
			};

		customers.Dump();
	}
}

// 分部类
public partial class CustomerList
{
	private string propertyName;
	private SortDirection direction;

	// 分部方法
	partial void SpecialSort(string propertyName, SortDirection direction)
	{
		this.propertyName = propertyName;
		this.direction = direction;

		Sort(Comparer);
	}

	/// <summary>
	/// Using an integer to change the direction of the sort was a suggestion made by 
	/// Chris Chartran, my good friend from Canada
	/// </summary>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <returns></returns>
	private int Comparer(Customer x, Customer y)
	{
		try
		{
			PropertyInfo lhs = x.GetType().GetProperty(propertyName);
			PropertyInfo rhs = y.GetType().GetProperty(propertyName);

			int directionChanger = direction == SortDirection.Ascending ? 1 : -1;

			object o1 = lhs.GetValue(x, null);
			object o2 = rhs.GetValue(y, null);

			if (o1 is IComparable && o2 is IComparable)
			{
				return ((IComparable)o1).CompareTo(o2) * directionChanger;
			}

			// no sort
			return 0;
		}
		catch (Exception ex)
		{
			Debug.WriteLine(ex.Message);
			return 0;
		}
	}
}

// 分部类
public partial class CustomerList : List<Customer>
{
	// 声明分部方法
	partial void SpecialSort(string propertyName, SortDirection direction);

	public void Dump()
	{
		SpecialSort("CustomerID", SortDirection.Descending);

		foreach (var customer in this)
			Console.WriteLine(customer.ToString());
	}
}


public class Customer
{
	public int CustomerID { get; set; }
	public string Name { get; set; }

	public override string ToString()
	{
		return string.Format("CustomerID={0}, Name={1}", CustomerID, Name);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面中可以对界面中显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面中查看签到种类信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值