委托、面向对象编程(Object-Oriented Programming(OOP)、事件
委托
委托(delegate)是一种可以把引用存储为函数的类型。(委托最重要的用途在本书后面介绍到事件和事件处理时才能解释清楚)在定义了委托后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace delegateWeituo
{
class Program
{
delegate double ProcessDelegate(double param1, double param2);//delegate 关键字指定该定义是用于委托的,而不是用于函数的(该定义所在的位置与函数定义相同)。接着,该定义指定 double 返回类型和两个 double 参数。实际使用的名称可以是任意的,所以可以给委托类型和参数指定任意名称。
static void Main(string[] args)
{
ProcessDelegate processD;//Main()中的代码首先使用新的委托类型声明一个变量
Console.WriteLine("enter 2 numbers 以逗号分隔");
string input = Console.ReadLine(); int commaPos=input.IndexOf(',');
double param1 = Convert.ToDouble(input.Substring(0,commaPos));
double param2 = Convert.ToDouble(input.Substring(commaPos+1,input.Length-1-commaPos));
Console.WriteLine("Enter M to multiple or D_otherinput to divide:");
input = Console.ReadLine();
if (input == "M")
processD = new ProcessDelegate(Multiply);//初始化 process 委托变量,要把一个函数引用赋给委托变量,类似于给数组赋值,必须使用 new 关键字创建一个新委托
else
processD = new ProcessDelegate(Divide);//该函数是 Multiply()或 Divide()。注意这个参数与委托类型或目标函数的参数不匹配,这是委托赋值的一个独特语法,参数是要使用的函数名,且不带括号。
//上面可改为process=Multiply;//process 变量的委托类型匹配函数的签名,于是自动产生化一个委托
Console.WriteLine("Result:{0}", processD(param1, param2)); Console.ReadKey();//无论委托引用的是什么函数,该语法都是有效的
}
private static double Multiply(double param1, double param2)
{
return param1 * param2;
}
static double Divide(double param1, double param2)
{
return param1 / param2;
}
}
}
delegate string ReadLineDelegate();//null param
static void Main(string[] args)
{
ReadLineDelegate readLine=new ReadLineDelegate(Console.ReadLine);//系统函数,可以传参数
Console.WriteLine("Type a string:");
string userInput = readLine(); Console.WriteLine("You typed:{0}", userInput); Console.ReadKey();
}
函数的名称和参数统称为函数的签名。可以定
义名称相同、但签名不同的多个函数——也称为函数的重载。也可以在结构类型中定义函数;;。个数不定的特定类型的参数可以通过参数数组来指定。参数可以指定为 ref 或 out,以
便给调用者返回值
面向对象编程(Object-Oriented Programming(OOP)
对象的类型在 OOP 中有一个特殊的名称:类。可以使用类的定义实例化对象,这表示创建该类的一个实例。“类的实例”和对象含义相同,注意“类”和“对象”是完全不同的概念。
本章将使用统一建模语言(Unified Modeling Language,UML)语法研究类和对象。UML 是为应用程序建模而设计的,从组成应用程序的对象,到它们执行的操作,到我们希望有的用例,应有尽有。
UML 的对象框中,方法显示在第三部分,其语法类似于字段和属性,但最后显示的类型是返回类型
在 UML 中,每个参数都带有下述标识符之一:in、out 或 inout。它们用于表示数据流的方向,其中out 和 inout 大致对应于第 6 章讨论的 C#关键字 out 和 ref。<String>.Length 和<String>.ToUpper()等。句点字符把对象实例名和属性或方法名分隔开来,方法名后面的()把方法与属性区分开来
构造阶段:对象最初进行实例化的时期。这个初始化过程称为构造阶段,由构造函数完成。。构造函数就是用于初始化数据的函数。
析构阶段:在删除一个对象时,常常需要执行一些清理工作,例如,释放内存,这由析构
函数完成。
事件
class Program
{
class CompareTwoNumEventEg
{
public delegate void DelegateMax(double first, double second);
// public delegate void DelegateMax2(int first, int second);
public event DelegateMax EventMax;
public void DoubleMax(double a,double b)
{
Console.WriteLine("判断2个数的大小:{0}and{1},,较大的是:",a,b);
EventMax(a,b);//此事件 同委托签名 2个参数
}
}
class CompareTest
{
static void Main(string[] args)
{
CompareTwoNumEventEg compare = new CompareTwoNumEventEg();
//。事件引发时 该委托将调用方法
compare.EventMax += new CompareTwoNumEventEg.DelegateMax(compare_EventMax);//订阅事件
compare.DoubleMax(2.44,3.45);//引发事件 同类下的方法
//compare.EventMax += new CompareTwoNumEventEg.DelegateMax2(compareint_EventMax);
Console.ReadKey();
}
//private static void compareint_EventMax(int first,int second)
//{
// if (first > second)
// {
// Console.WriteLine(first);
// }
// else Console.WriteLine(second);
//}
static void compare_EventMax(double first, double second)
{
if (first > second)
{
Console.WriteLine(first);
}
else Console.WriteLine(second);
}
}
}
事件例子2
using System.Threading;
namespace DelegateandEvent
{
/// 委托 (这就是那个打小报告 的)
/// </summary>
/// <param name="sender">触发事件的源</param>
/// <param name="e">同时所携带的参数</param>
public delegate void DelegateClassHandle(object sender,CustomEventArgs e);
public class Exployer
{
/// <summary>
/// DelegateClassHandle类型的事件
/// </summary>
public event DelegateClassHandle PlayGameEvent;
string _name;//员工姓名
public string Name//可不弄?
{
get { return _name; }
set { _name = value; }
}
int _number;//员工姓名 、所在工位
public int Number
{
get { return _number; }
set { _number = value; }
}
public Exployer(string na,int Gongwei)//构造函数,用来初始化这2个值
{
_name = na;
_number = Gongwei;
}
public void GameOper()
{
if (PlayGameEvent != null)
{
Console.WriteLine("哈哈,,我要打游戏了 ");
CustomEventArgs e = new CustomEventArgs();//实例化一个参数类
e.Name = _name;
e.Number=_number;
PlayGameEvent(this,e);//触发事件
}
}
}
//具体报告的类 执行的方法在里面
public class BaoGaoCls
{
public void Notify(object sender,CustomEventArgs e)
{
System.Threading.Thread.Sleep(966);
Console.WriteLine("报告老板 ,{0}在{1}玩游戏。", e.Name, ((Exployer)sender).Number);//e.Number
}
}
public class CaiWuChu//触发后 另一个处理的类 财务开罚单
{
public void Penalty(object sender,CustomEventArgs e)
{
System.Console.WriteLine("被罚款人:"+e.Name+",被罚款人工号:"+((Exployer)sender).Number+",因上班玩游戏,罚5个月工资");
}
}
public class CustomEventArgs : EventArgs
{
string name = "";//员工 姓名
public string Name//员工姓名属性 读 写
{
get { return this.name; }
set { this.name = value; }
}
int number = 0;//所在办公室编号
public int Number//所在办公室编号属性 读 写
{
get { return this.number; }
set { this.number = value; }
}
public CustomEventArgs()//构造function
{
}
}
class Program
{
static void Main(string[] args)//办公室执行
{
Exployer DingYiChuCls = new Exployer("何和漳",566);//实例化一个员工对象
BaoGaoCls bgCls = new BaoGaoCls();
CaiWuChu caiwuFaKuan = new CaiWuChu();
//指明玩游戏这个事件 触发后,由谁来处理 关联起来 (订阅事件) 事件用委托来实例化
DingYiChuCls.PlayGameEvent += new DelegateClassHandle(bgCls.Notify);
DingYiChuCls.PlayGameEvent += new DelegateClassHandle(caiwuFaKuan.Penalty);//指明玩游戏这个事件 触发后,由谁来处理 关联起来 (订阅事件)
//DingYiChuCls.PlayGameEvent -= new DelegateClassHandle(caiwuFaKuan.Penalty);//指明玩游戏这个事件 触发后,由谁来处理 关联起来 (订阅事件)
DingYiChuCls.GameOper();//触发事件
Console.ReadKey();
}
}
}
Remind
string str = "string.Format处理如下: {0}的年纪是{1}";
string Xianstr = string.Format(str,e.Name,e.Age);
MessageBox.Show(Xianstr);