天天看点

C#学习之C#面向对象编程(委托(1))

委托

​ 委托是C#编程语言新提出的面向对象概念。委托其实就是把程序的某些功能交给其他地方的代码来实现。因为有些时候程序的流程并不确定,所以不自己实现,这些不确定的调用只能通过其他的外部程序来确定。

​ 这时候我们就需要委托,在外部程序中指定应该调用的方法来完成这个功能。委托类似于C++中的函数指针,当并不完全相同。因为委托概念是面向对象的,所以委托必须封装在类内部。委托能够对应多个方法,可以在程序运行时动态加减。

1. 委托的定义

​ C#编程语言要求开发人员非常熟悉委托,并且能够根据代码实现的场景,声明和使用委托。委托常用的场合大致分为以下4个方面。

  • 一个类中需要调用不确定的方法时
  • 在类中声明事件时
  • 在类中调用不应在类中实现的方法时
  • 在接口中调用其他接口的方法时

​ 面向对象编程,需要使用类将事物封装成相对独立的单元,减少了外部程序对类所包含数据的干扰,但是事物与事物之间总是由各种各样的关系,所以封装在一定程度上为编程带来了麻烦,委托就是为了处理此类的问题。

​ 使用委托的好处是当外部条件改变时,不用修改每个调用类的定义。委托降低了类与类之间互相调用的耦合程度。

​ 委托的定义包括三个方面,首先使用delegate关键字表示将要声明一个委托,接着是委托的数据类型,最后是委托的名称和参数列表。

public delegate decimal Price Adjustment(Order AdjustmentOrder);

​ 委托代码案例:

using System;

namespace cn.wellswang
{
	public class Order
	{
		public string CoffeeName { get; set; }
		public int AreaID { get; set; }
		public decimal BasePrice { get; set; }
		// 声明价格调整的委托
		public delegate decimal PriceAdjustmentDelegate(Order AdjustmentOrder);
		// Order类的委托实例变量
		public PriceAdjustmentDelegate PriceAdjustment;
		public decimal FinalPrice
		{
			get
			{
				return BasePrice + PriceAdjustment(this);
			}
		}
	}
	public class Adjustment
	{
		private decimal Addition = 0;
		public decimal BikePrice(Order AdjustmentOrder)
		{
			Addition += 5m;
			return Addition;
		}
		public decimal CarPrice(Order AdjustmentOrder)
		{
			Addition += 10m;
			return Addition;
		}
		public decimal Foam(Order AdjustmentOrder)
		{
			Addition += 0.5m;
			return Addition;
		}
		public decimal Heat(Order AdjustmentOrder)
		{
			Addition += 1m;
			return Addition;
		}
	}
	public class Sale
	{
		public Order SaleOrder { get; set; }
		public Adjustment SaleAdjsutment { get; set; }
		public void DoSale()
		{
			switch (SaleOrder.AreaID)
			{
				case 1:
					SaleOrder.PriceAdjustment += 
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.BikePrice);
					SaleOrder.PriceAdjustment +=
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.Foam);
					break;
				case 2:
					SaleOrder.PriceAdjustment += 
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.CarPrice);
					SaleOrder.PriceAdjustment +=
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.Foam);
					break;
				case 3:
					SaleOrder.PriceAdjustment += 
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.CarPrice);
					SaleOrder.PriceAdjustment +=
						new Order.PriceAdjustmentDelegate
						(SaleAdjsutment.Heat);
					break;
			}
		}
	}
  public class Test
	{
		public static void Main(string[] args)
		{
			Sale MySale = new Sale();
			MySale.SaleOrder = new Order();
			MySale.SaleOrder.BasePrice = 30;
			MySale.SaleOrder.AreaID = 3;
			MySale.SaleAdjsutment = new Adjustment();
			MySale.DoSale();
			Console.Write("最终价格:" + MySale.SaleOrder.FinalPrice.ToString()); // 41
		}
	}
}
           
2. 事件委托

​ 在C#编程语言中,事件必须声明为委托类型,没有声明方法的事件是没有意义的。事件,相当于委托实例变量,说不同的是声明事件的代码中多了一个event关键字。

​ 事件与委托类的实例变量很相似,在这个实例变量中可以添加、移除符合委托声明的方法。这也意味着可以用多种方法处理一个事件。最为常见的是一个事件对应一个处理方法。

using System;

namespace cn.wellswang
{
	public class LoginEvent : EventArgs
	{
		public string UserName { get; set; }
		public string PassWord { get; set; }
		public LoginEvent(string username, string password)
		{
			UserName = username;
			PassWord = password;
		}
	}
	public class Login
	{
		public string UserName { get; set; }
		public string PassWord { get; set; }
		public delegate void LoginHandler(LoginEvent e);
		public event LoginHandler OnLogin;
		public void ActiveLogin()
		{
			OnLogin(LoginEvent(UserName, PassWord));
		}
	}
	public class LoginPage
	{
		private Login UserLogin = new Login();
		private bool IfLogined = false;
		public string URLToShow;
		public void DoLogin()
		{
			UserLogin.UserName = "Wells";
			UserLogin.PassWord = "001005";
			UserLogin.OnLogin += new Login.LoginHandler(VerifyUser);
			UserLogin.OnLogin += new Login.LoginHandler(ShowOrders);
			UserLogin.ActiveLogin();
		}
		void VerifyUser(LoginEvent e)
		{
			if (e.UserName == "Wells" && e.PassWord == "001005")
			{
				IfLogined = true;
			}
		}
		void ShowOrders(LoginEvent e)
		{
			if(IfLogined)
			{
				URLToShow = "报销单审核情况.aspx";
			}
		}
	}
}
           

​ 事件本身包含一个调用列表,在事件产生时,按照列表的顺序执行指定的方法。

​ 事件委托和一般委托是很相似的,不同点就在于这个调用列表,事件委托的调用列表只能通过"+=“运算符和”-=“运算符来改变,而一般委托可以使用”="运算符,直接使用一个调用列表给委托赋值。事件委托的这种赋值方式,在一定程度上,避免了事件调用列表的方法被某段程序代码完全替换。

上一篇: C#网络编程