zoukankan      html  css  js  c++  java
  • .Net之美读书笔记3

    委托

    委托的定义

    委托(delegate)可以理解为函数类型,实现了函数可以当作参数传递,使程序更加灵活。下面通过代码快速熟悉委托的使用顺序。

            //1. 声明委托类型
            public delegate void GreetingDelegate(string name);
    	class Program
    	{
    		//2.定义委托方法体
    		public static void EnglishGreeting(string name)
    		{
    			Console.WriteLine("Morning," + name);
    		}
    
    		public static void ChineseGreeting(string name)
    		{
    			Console.WriteLine("早上好," + name);
    		}
    
    		public static void GreetPeople(string name, GreetingDelegate markGreet)
    		{
    			//4.调用委托
    			markGreet(name);
    		}
    		static void Main(string[] args)
    		{
    			//3.将函数赋值给委托
    			GreetPeople("Jerry Zhao", EnglishGreeting);
    			GreetPeople("番茄赵", ChineseGreeting);
    			Console.ReadKey();
    		}
    

    事件

    事件(event):对委托的封装,保护委托不允许外部程序直接为委托赋值(会将已添加的委托丢掉)。
    使用方法public event GreetingDelegate MarkGreet;

    .Net事件模型

    这里借助一个熟悉的例子讲诉事件模型。热水器烧水到95后,报警器报警,显示器显示。

      	/// <summary>
    	/// 加热器
    	/// </summary>
    	public class Heater
    	{
    		private int temperature;
    		/// <summary>
    		/// 型号
    		/// </summary>
    		public string type = "RealFire 001";
    		/// <summary>
    		/// 产地
    		/// </summary>
    		public string area = "China Xian";
    
    		/// <summary>
    		/// 委托
    		/// </summary>
    		/// <param name="sender">被观察者(Heater)</param>
    		/// <param name="e">传递到观察者的参数</param>
    		public delegate void BoiledEnentHandler(object sender, BoiledEventArgs e);
    		/// <summary>
    		/// 初始化空函数,防止没有订阅值为null,调用报错
    		/// </summary>
    		public event BoiledEnentHandler Boiled = (sender, e) => { };
    
    		/// <summary>
    		/// 注意这里使用内部类,只是传递参数
    		/// 被观察着传入到观察者参数
    		/// </summary>
    		public class BoiledEventArgs : EventArgs
    		{
    			public readonly int temperature;
    
    			public BoiledEventArgs(int temperature)
    			{
    				this.temperature = temperature;
    			}
    		}
    
    		/// <summary>
    		/// 被观察者通知观察者方法
    		/// </summary>
    		/// <param name="e">参数</param>
    		protected virtual void OnBoiled(BoiledEventArgs e)
    		{
    			//#1多播委托
    			/*
    			foreach(Delegate d in Boiled.GetInvocationList())
    			{
    				BoiledEnentHandler boiled = (BoiledEnentHandler)d;
    				boiled(this, e);
    			}
    			*/
    
    			//#2异常处理,一个主题有多个订阅者。订阅者一个订阅者发出异常不应该阻塞其他订阅者
    			/*
    			foreach (Delegate d in Boiled.GetInvocationList())
    			{
    				BoiledEnentHandler boiled = (BoiledEnentHandler)d;
    				try
    				{
    					boiled(this, e);
    				}
    				catch (Exception ex)
    				{
    
    					
    				}
    			}
    			*/
    
    			//#3超时处理,发布者不应这个通知订阅者,应采用一部调用
    			foreach (Delegate d in Boiled.GetInvocationList())
    			{
    				BoiledEnentHandler boiled = (BoiledEnentHandler)d;
    				boiled.BeginInvoke(this, e, null, null);
    
    			}
    
    			//Boiled(this, e);
    		}
    
    		/// <summary>
    		/// </summary>
    		public void BoilWater()
    		{
    			for (int i = 0; i <= 100; i++)
    			{
    				temperature = i;
    				if (temperature > 95)
    				{
    					BoiledEventArgs e = new BoiledEventArgs(temperature);
    					OnBoiled(e);
    				}
    			}
    		}
    	}
    
        
    	/// <summary>
    	/// 报警器
    	/// </summary>
    	public class Alarm
    	{
    		public void MarkAlert(object sender, Heater.BoiledEventArgs e)
    		{
    			Heater heater = (Heater)sender;
    			Console.WriteLine("Alarm:{0}-{1}", heater.area, heater.type);
    			Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度", e.temperature);
    			Console.WriteLine();
    			Thread.Sleep(500);
    		}
    	}
    
    	/// <summary>
    	/// 显示器
    	/// </summary>
    	public class Display
    	{
    		public static void ShowMsg(object sender, Heater.BoiledEventArgs e)
    		{
    			Heater heater = (Heater)sender;
    			if (e.temperature == 99)
    			{
    				Thread.Sleep(2000);
    			}
    
    			Console.WriteLine("Display:{0}-{1}", heater.area, heater.type);
    			Console.WriteLine("Display:水已经{0}度", e.temperature);
    			Console.WriteLine();
    			
    		}
    	}
    
            //调用
            static void Main(string[] args)
    		{
    			Heater heater = new Heater();
    			Alarm alarm = new Alarm();
    
    			heater.Boiled += alarm.MarkAlert;
    			heater.Boiled += Display.ShowMsg;
    			heater.BoilWater();
    
    			Console.ReadKey();
    		}
    

    委托进阶

    利用上面的代码介绍下多播的进阶

    • 1多播委托的调用
    • 2异常处理,多播中异常处理
    • 3超时处理,委托的异步调用成对出现 BeginXXX,EndXXX
  • 相关阅读:
    django集成django-xadmin
    Django设置 DEBUG=False后静态文件无法加载解决
    Django ORM必会的查询方法
    django admin-过滤器
    Django settings.py 中设置访问 MySQL 数据库【一种是直接在 settings.py 文件中直接写数据库信息,另一种是读文件获取数据库信息】
    django-admin之ModelAdmin最全解释
    SPL(Standard PHP Library 标准PHP类库)
    rsync 数据同步
    PHP 安装memcache.so 和memcached.so
    linux 安装memcached
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/8026591.html
Copyright © 2011-2022 走看看