欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

C#基础教程二

时间:2023-06-01
C#基础教程二

类与对象

概述

基本概念类、方法和变量对象的创建及使用 类的方法与属性

方法定义方法调用方法中的参数传递方法重载类方法扩展实例 构造函数和析构函数

构造函数析构函数 封装性

概述属性索引器 类的继承

概述base使用 多态

概述实现多态的方式虚方法与重写抽象类与抽象方法 猜拳游戏系统登录用户类继承与多态实例 接口

接口概念接口声明接口应用接口实例 委托

委托定义委托声明委托应用匿名方法委托实例 事件

事件定义事件使用事件实例 类与对象 概述

面向对象程序设计(Object Oriented Programming,OOP)= 对象+类+继承+多态+消息。
程序由一系列对象组成。
类是现实世界抽象,包括数据和方法,对象是类的实例化。
对象间通过消息传递相互通信。

基本概念 对象
对象是现实世界中事物存在的实体,分为静态部分(属性)和动态部分(可以变化的行为)。类
类是具有相同属性和功能的对象的抽象集合,是C#的核心和基本构成模块。
类是一种抽象的数据类型,是对一类对象的统一描述。

类是对象的定义,包含对象的信息,名称、方法、属性和事件。类并不是对象,因为它不存在于内存中。

类、方法和变量 类的定义

类定义可在多个源文件间拆分,partial。

[类修饰符] class 类名{类的主体}

类修饰符:

public:共有,访问不受限制。private:私有,私有成员只在声明的类或结构体中才可访问。protected:保护,类内部及继承类中才能访问。internal:内部,同一程序集内所有类可访问,一般限于本项目内。protected internal:内部保护,限于本项目或子类访问。 类的成员变量

[访问修饰符] 数据类型 <成员变量名>

static修饰用于静态成员。
非静态类中可以出现[非]静态成员,静态类中只能出现静态成员。
非静态方法中可以访问[非]静态成员,静态方法中只能访问静态成员。
调用方法不同,实例方法需要对象调用,即对象名.方法名,静态方法使用类调用,即类名.方法名。
静态类不允许创建对象。
工具类,可以考虑使用静态类(Console类),资源共享,但占用内存大。

类的成员方法的定义

[访问修饰符] 返回值类型 <方法名> ([参数列表]){成员方法体}

public class Car{public double Number;public string Make;public string Model;public string show(){return string.Format("排量:{0}T,厂家:{1},型号:{2}",Numbetr,Make,Model);}}

对象的创建及使用

类是广义的数据类型,包含数据和数据的方法。
new建立类的新实例(对象)。

对象的创建和使用
(1)先声明对象,再创建对象初始化。

Car myCar;myCar = new Car();

(2)声明并创建对象。

Car myCar = new Car();

访问类成员
(1)类内部访问。

this可省略。

this.类成员

this也可用于执行构造函数。

public class Test{public Test(){Console.WriteLine("无参构造函数");}//先执行Test(),后执行Test(string text)public Test(string text):this(){Console.WriteLine(text);Console.WriteLine("有参构造函数");}}

(2)类外部调用。

对象名.成员

string str;Car myCar = new Car();myCar.Number = 2.0;myCar.Make = "中国吉利";myCar.Model = "GL";str = myCar.show();

类的方法与属性

类的方法指对象执行的操作,类的属性指对象所拥有的特征。

方法定义

方法是将完成同一功能的内容放在一起,方便书写和调用。

访问修饰符 修饰符 返回值类型 方法名(参数列表){语句块;}

public double Add(double num1, double num2){return num1+num2;}

访问修饰符:public等,省略默认为private。修饰符:virtual(虚拟的)、abstract(抽象的)、override(重写的,用于继承)、static(静态的)、sealed(密封的)。返回值类型:任意数据类型,void表示无返回值。方法名:方法功能的描述。参数列表:0到多个参数。”数据类型 参数名“,多参数逗号隔开。语句块:方法体,执行的代码块。 方法调用

使用方法的过程。

方法名(参数列表);

方法中的参数传递

方法调用从外部传递的参数是实参,方法内部接收的参数是形参。
形参调用时才分配内存,调用结束释放内存,只在方法内部有效。

值类型参数

无任何修饰符,按值传递,形参和实参互不影响。

public void Swap(int x, int y) {}

引用型参数

传递变量引用,实参和形参的引用指向内存中的同一位置。形参的更改会影响实参指向的变量。方法定义和调用都必须使用ref。

public void Swap(ref int x, ref int y) {int tmp;tmp = x;x = y;y = tmp;}int a = 6, b = 8;Swap(ref a, ref b);

输出型参数

不创建新的存储位置,形参使用实参的存储位置,方法定义和调用都使用out。

public void Add(out int a) {a = 1;}int a;Add(out a);

数组型参数

传递数组时,是引用传递,形参数组不能定义数组长度。
形参数组前不添加params修饰符,实参必须是数组名;形参数组前添加params修饰符,实参可以是数组名,也可以是数组元素值的列表(数据列表)。
params修饰符要点:

可以修饰任何类型参数;只能修饰一维数组;不允许params数组使用ref或out;每个方法只能有一个params数组。

public int max1(int []a){int k = 0;for(int i=0;ia[k])k = i;}return a[k];}public int max2(params int []a){int k = 0;for(int i=0;ia[k])k = i;}return a[k];}int[] x = new int[]{1,2,3,4,5};max1(x);max2(x);max2(1,2,3,4,5);

方法重载

定义多个方法名相同、参数列表(参数类型、参数个数)不同的方法。

int auto(int a, int b){return a+b;}string auto(string a, string b){return a+b;}int auto(int a, int b, int c){return a+b+c;}

类方法扩展实例

Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace experiment2{ static class MyExtensions {//类名不固定 //是否对称字符串 public static bool IsPalindrome(this string str){ for(int i = 0, j = str.Length-1; i < j; i++, j--) if(str[i] != str[j]) return false; return true; }//数字反转 public static int ReverseDigits(this int num){//方法内num值的修改不会影响外部值int Reverse_num = 0;while(num!=0){Reverse_num *= 10;Reverse_num += num%10; num /= 10;} return Reverse_num; } } class Program{ static void Main(string[] args){ Console.Write("Enter a string: "); string str = Console.ReadLine(); Console.WriteLine(""" + str + """ + (str.IsPalindrome() ? " is " : " is not ") + "a palindrome"); Console.Write("Enter an integer: "); int a = int.Parse(Console.ReadLine()); Console.WriteLine("The reverse of " + a.ReverseDigits() + " is " + a); Console.ReadKey(); } }}

csc Program.cs

构造函数和析构函数

对象初始化和回收对象资源。

构造函数

构造方法,类的特殊成员方法,用来完成类的成员变量的自动初始化。
若编写了构造函数,系统不会提供默认构造函数。

无参构造函数

[访问修饰符] <类名>(){构造函数的主体}

class Employee{public Employee(){}}

有参构造函数

[访问修饰符] <类名>([参数列表]){构造函数的主体}

class Employee{private string name;public Employee(string n){ name = n;}}

析构函数

垃圾回收机制,当类实例不再有效,并符合析构条件时,会调用该类的析构函数。

~<类名>(){析构函数主体}

封装性 概述

面向对象编程语言中,编程单元是类,通过类封装数据和操作,类对外提供接口来访问和操作。
封装(Encapsulation)用于对外部进行隐藏类的内部。
支持封装的修饰符:

privateprotectedinternalprotected internalpublicother encapsulating strategy(其他封装策略):属性和索引器。 属性

属性提供将对象的读写和操作关联起来的机制,是一种特殊方法(访问器)。

class Person{private string name;private int age;public void SetName(string n){this.name = n;}public void SetAge(int a){this.age = a;}public string GetName(){return this.name;}public int GetAge(){return this.age;}}string name;int age;Person p = new Person();p.SetName("ma");p.SetAge(30);name = p.GetName();age = p.GetAge();

class Person{private string name;private int age;public string Name(){set{this.name = value;}get{return this.name;}}public int Age(){set{this.age = value;}get{return this.age;}}}string name;int age;Person p = new Person();p.Name = "ma";p.Age = 30;name = p.Name;age = p.Age;

属性是像类的字段一样的访问方法。属性只能包含一个get访问器和一个set访问器,不能含其他方法、字段等。get访问器返回属性类型值。 索引器

索引器用于简化类中数组或集合成员的存取操作。

[修饰符] 数据类型 this[索引类型 index] {get{//获得属性的代码}set{//设置属性的代码}}

public class ID{private string[] name = new string[2];public string this[int index] {get{return name[index];}set{name[index] = value;}}}string name;ID id = new ID();id[0] = "ma";id[1] = "hong";name = id[0];

索引器与数组的区别:

数组索引值为整数,索引器索引值(Index)不限定为整数。索引器允许重载。索引器不是变量,未定义直接存储数据的内存,数组有。索引器有get和set访问器。

索引器与属性的区别:

索引器以方法签名(this)标识,属性采用名称标识。索引器可以重载,属性不可以。索引器不能用static声明(索引器属于实例成员),属性可以。 类的继承 概述

继承已有类的成员(数据和方法),方便创建和维护程序,重用代码有利于节省开发时间。
已有类为基类,继承类为派生类。

<访问修饰符> class<基类名称> {基类主体部分}class <派生类>:<基类名称> {派生类主体部分}

public class Car{private string type;public string Type(){set{this.type = value;}get{return this.type;}}}public class ChineseCar:Car{private string nation;public string Nation(){set{this.nation = value;}get{return this.nation;}}}string type;string nation;ChineseCar car = new ChineseCar();car.Type = "type1";car.Nation = "China";type = car.Type;nation = cat.Nation;

构造函数和析构函数不能被继承派生类中同名成员会覆盖基类同名成员(不会删除)。基类定义虚方法、虚属性及虚索引器,派生类重载,从而实现多态。派生类只能单一继承,接口可实现多重继承。 base使用

base用于派生类中访问基类公有或保护成员的访问,只局限在构造函数,实例方法和实例属性访问器中。

base调用基类构造方法;

class Car(){public string type;public Car(){car = "货车";}}class ChineseCar:Car{public string nation;public ChineseCar():base(){nation = "中国";}}

base在派生类中调用基类方法。

class Car(){public void AddCar(){}}class ChineseCar:Car{public void AddTypee(){base.AddCar();}}

多层继承中:

重载存在,base指向直接继承的父类成员的方法;无重载存在,base指向任何上级父类的公有或保护方法。 多态 概述

同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

编译时多态:重载实现,非虚成员,系统在编译时,根据传递的参数、返回类型等信息决定操作。运行时多态:重写虚函数实现,系统运行时,根据实际情况决定操作。 实现多态的方式

多个类继承同一个类,继承实现多态,派生类重写基类成员。抽象类被派生类扩充使用,抽象类实现多态,抽象类中部分或全部未实现的成员在派生类中全部实现;抽象类中已实现成员仍可被重写。多个类实现相同接口,接口实现多态。 虚方法与重写

虚方法重载,派生类中实现对基类虚方法的重新定义。

声明虚方法:

[访问修饰符] virtual [返回类型] ([参数列表]) {虚方法实现部分}

派生类中覆盖同名方法使用override。

public class oblong{protected double x, y;public const double p = Math.PI;public oblong(double x1, double y1){x = x1;y = y1;}public virtual double Area(){return x*y;}}public class round:oblong{public round(double r):base(r, 0){}public override double Area(){return p*x*x;}}round r = new round(2);r.Area();oblong ob = new oblong(2,3);ob.Area();

派生类中创建同名方法使用new。

public class oblong{protected double x, y;public const double p = Math.PI;public oblong(double x1, double y1){x = x1;y = y1;}public virtual double Area(){return x*y;}}public class round:oblong{public round(double r):base(r, 0){}public new double Area(){return p*x*x;}}round r = new round(2);r.Area();oblong ob = new oblong(2,3);ob.Area();

override和new的相同点是定义与基类相同的方法,派生类对象执行各自的派生类中的方法;
不同点是派生类对象向上转型后,重写(override)基类调用派生类方法,隐藏(new)基类调用基类方法。

抽象类与抽象方法

抽象类是不能被实例化的类(至少含有一个抽象方法,抽象方法必须实现),只能用来派生类。
抽象方法只能声明,派生类中实现。

[访问修饰符] abstract class 类名{//抽象类成员定义}[访问修饰符] abstract void 方法名(方法参数);

public abstract class oblong{protected double x, y;public const double p = Math.PI;public oblong(double x1, double y1){x = x1;y = y1;}public abstract double Area();}public class round:oblong{public round(double r):base(r, 0){}public override double Area(){ //override或new都行return p*x*x;}}public class retangle:oblong{public retangle(double l, double w):base(l, w){}public override double Area(){ //override或new都行return x*y;}}round r = new round(2);r.Area();rectangle ra = new rectangle(2,3);ra.Area();//错误//oblong b = new oblong(2,3);

猜拳游戏

Program.cs

using System;namespace Game{ class Program{ static void Main(string[] args){ Player p1 = new Player(){ Name = "Tony" }; Computer c1 = new Computer(); Judge j1 = new Judge(); while(true){ int res1 = p1.ShowFist(); int res2 = c1.ShowFist(); j1.Determine(res1, res2); Console.ReadKey(); } } }}

Player.cs

using System;namespace Game{ class Player{ string name; public string Name{ get { return name; } set { name = value; } } public int ShowFist(){ Console.WriteLine("请问,你要出什么拳? 1.剪刀 2.石头 3.布"); int result = ReadInt(1, 3); string fist = IntToFist(result); Console.WriteLine("玩家{0}出了{1}", name, fist); return result; } private string IntToFist(int input){ string result = string.Empty; switch(input){case 1:result = "剪刀";break;case 2:result = "石头";break;case 3:result = "布";break; } return result; } private int ReadInt(int min, int max){ while(true){ //从控制台获取用户输入的数据 string str = Console.ReadLine(); //将用户输入的字符串转换成Int类型 int result; if(int.TryParse(str, out result)){ //判断输入的范围 if(result >= min && result <= max){ return result; }else{ Console.WriteLine("请输入1个{0}-{1}范围的数", min, max); continue; } }else{ Console.WriteLine("请输入整数"); } } } }}

Computer.cs

using System;namespace Game{ class Computer{ //生成一个随机数,让计算机随机出拳Random ran = new Random(); public int ShowFist(){ int result = ran.Next(1, 4); Console.WriteLine("计算机出了{0}", IntToFist(result)); return result; } private string IntToFist(int input){ string result = string.Empty; switch(input){case 1:result = "剪刀";break;case 2:result = "石头";break;case 3:result = "布";break; } return result; } }}

Judge.cs

using System;namespace Game{ class Judge{ public void Determine(int p1, int p2){ if(p1 - p2 == -2 || p1 - p2 == 1){ Console.WriteLine("玩家胜利!"); }else if(p1 == p2){ Console.WriteLine("平局!"); }else{ Console.WriteLine("玩家失败!"); } } }}

csc Program.cs Player.cs Computer.cs Judge.cs

系统登录用户类

Program.cs

using System;namespace myGame{ class Program{ static void Main(string[] args){ gameUser guer1 = new gameUser("剑士", "123456"); Console.WriteLine("玩家:" + guer1.Username + ", 密码:" + guer1.Password); Console.Read(); } }}

gameUser.cs

namespace myGame{ class gameUser{ private string username; public string Username{ get { return username; } set { username = value; } } private string password; public string Password{ get { return password; } set { password = value; } } public gameUser(){} public gameUser(string username,string password){ this.username = username; this.password = password; } }}

csc Program.cs gameUser.cs

继承与多态实例

Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;public class POS{ private string area; public POS(string area){ this.area = area; } //public string Area{ get; set; } //始终为空,即使area有值public string Area{ get {return area;} set {area=value;} } }public interface IPayable{ void Pay(decimal money, POS pos);}class BankCard{ private string _account; decimal _savings; public BankCard(string account){ _account = account; } public virtual void Query(){ // 查询 Console.WriteLine("银行卡{0}上余额为{1}", _account, _savings); } public virtual void Deposit(decimal money){ // 存款 _savings += money; _savings = Math.Round(_savings, 2); } public virtual void Draw(decimal money){ // 取款 if (_savings >= money){ _savings -= money; _savings = Math.Round(_savings, 2); }else Console.WriteLine("余额不足"); } class PayableCard : BankCard, IPayable{ public PayableCard(string account):base(account){ //_account = account; } public virtual void Pay(decimal money, POS pos){ if(_savings >= money){ _savings -= money; _savings = Math.Round(_savings, 2); Console.WriteLine("支付{0}元", money); }else Console.WriteLine("余额不足,无法进行支付"); } } class LocalCard : PayableCard{ private string area; public LocalCard(string account, string area):base(account){ //_account = account; this.area = area; } public override void Pay(decimal money, POS pos){ if(area == pos.Area){ if(_savings >= money){ _savings -= money; _savings = Math.Round(_savings, 2); Console.WriteLine("支付{0}元", money); } else Console.WriteLine("余额不足,无法进行支付"); }else Console.WriteLine("本地卡不支持异地支付.");//银行卡和POS机不是同一个地方 } } class GlobalCard : PayableCard{ private string area; decimal _rate = 0.01m; public GlobalCard(string account, string area):base(account){ //_account = account; this.area = area; } public override void Pay(decimal money, POS pos){ if(area != pos.Area){ _savings -= money * (1 + _rate); _savings = Math.Round(_savings, 2); Console.WriteLine("支付{0}元,手续费{1}元", money * (1 + _rate), money * _rate); }else{ _savings -= money; _savings = Math.Round(_savings, 2); Console.WriteLine("支付{0}元", money); } } } class CreditCard : PayableCard{ decimal _limit; decimal overdraw; public CreditCard(string account, decimal limit):base(account){ //_account = account; _limit = limit; } public override void Pay(decimal money, POS pos){ if(_savings < 0) overdraw = -_savings; else overdraw = 0; if(_savings + _limit < money) Console.WriteLine("支付超出透支额度."); else{ _savings -= money; _savings = Math.Round(_savings, 2); Console.WriteLine("支付{0}元", money); } Console.WriteLine("透支额度为{0}", _limit); Console.WriteLine("欠款为{0},余额为{1}", overdraw, _savings); } } class Program{ static void Main(string[] args){ POS pos1 = new POS("010"); POS pos2 = new POS("021"); BankCard[] cards = new BankCard[4]; cards[0] = new BankCard("bj10000001"); cards[1] = new LocalCard("bj90000009", "010"); cards[2] = new GlobalCard("sh30000001", "021"); cards[3] = new CreditCard("sh80000008", 10000); for(int i = 0; i < cards.Length; i++){ cards[i].Deposit(2200); Console.WriteLine("{0}支付前", cards[i]); cards[i].Query(); if(cards[i] is IPayable){ ((IPayable)cards[i]).Pay(1000, pos1); ((IPayable)cards[i]).Pay(1190, pos2); } Console.WriteLine("{0}支付后", cards[i]); cards[i].Query(); Console.WriteLine(); } } }}

csc Program.cs gameUser.cs

接口

C#类不支持多重继承,通过接口实现多重继承。

接口概念

接口是契约、标准,只能定义方法、属性、索引器和事件等成员(不能实现),与抽象类类似(但接口所有成员完全抽象)。
类可以继承多个接口,接口可以继承接口,类可以通过继承基类(或接口)多次继承同一个接口。

接口特点:

类似抽象基类,继承接口的非抽象类必须实现接口。接口不能直接实例化。接口可包含事件、索引器、方法和属性。接口不包含方法的实现。类和结构可从多个接口继承。接口自身可从多个接口继承。 接口声明

修饰符 interface 接口名称:继承的接口列表{接口内容;}

接口中成员默认public,不允许添加访问修饰符。

interface Information{string Code{get;set;}string Name{get;set;}void ShoowInfo();}

接口应用

账户接口1,所有银行账户类都要继承此接口,基本功能。

public interface IBankAccount{void PayIn(decimal amount); //存钱bool Withdraw(decimal amount);//取钱decimal Balance{get;}//余额}

普通账户类1

public class SaverAccount:IBankAccount{private decimal balance;public void PayIn(decimal amount){balance += amount;}public bool Withdraw(decimal amount){if(balance>=amount){balance -= amount;return true;}else{Console.WriteLine("余额不足!");return false;}}public decimal Balance{get{return balance;}}public override string string ToString(){return String.Format("Saver Bank balance:", balance);}}

账户接口2,包含高级银行账户的一些额外功能。

public interface IBankAdvancedAccount{void DealStartTip(); //交易开始提示void DealStopTip();//交易结束提示}

金卡账户类2

public class GoldAccount:IBankAccount,IBankAdvancedAccount{private decimal balance;public void PayIn(decimal amount){balance += amount;}public bool Withdraw(decimal amount){if(balance>=amount){balance -= amount;return true;}else{Console.WriteLine("余额不足!");return false;}}public decimal Balance{get{return balance;}}public override string string ToString(){return String.Format("Saver Bank balance:", balance);}public void DealStartTip(){Console.WriteLine("交易开始,请注意周围环境!");}public void DealStopTip(){Console.WriteLine("交易结束,请带好你的贵重物品,欢迎下次光临!");}}

接口实例

Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;//Array.Sort()方法需要数组中元素实现IComparable接口public class Person : IComparable{ public string FirstName; public string LastName; public DateTime Birthday; public Person() { } public Person(string FirstName, string LastName, DateTime Birthday){ this.FirstName = FirstName; this.LastName = LastName; this.Birthday = Birthday; } public int CompareTo(Person p){ if(this.LastName.CompareTo(p.LastName) == 0) return this.FirstName.CompareTo(p.FirstName); else return this.LastName.CompareTo(p.LastName); } public override string ToString(){ return "FirstName=" + FirstName + ", " + "LastName=" + LastName + ", " + "Birthday=" + Birthday; }}//实现IComparer接口的比较类class PersonComparer : Person, IComparer{ public PersonComparer(){ this.Birthday = Birthday; } public int Compare(Person p1, Person p2){ return p1.Birthday.CompareTo(p2.Birthday); }}class Program{ static void Main(string[] args){ Person[] persons = new Person[]{new Person { FirstName = "Damon", LastName = "Hill", Birthday = new DateTime(1990, 5, 1) },new Person { FirstName = "Niki", LastName = "Lauda" , Birthday = new DateTime(1995, 10, 4) },new Person { FirstName = "Ayrton", LastName = "Senna" , Birthday = new DateTime(1992, 6, 23) },new Person { FirstName = "Graham", LastName = "Hill" , Birthday = new DateTime(1994, 9, 15) } }; Console.WriteLine("Order by name:"); Array.Sort(persons); foreach(var p in persons) Console.WriteLine(p); Console.WriteLine("Order by Birthday:"); Array.Sort(persons, new PersonComparer()); foreach var p in persons) Console.WriteLine(p); }}

csc Program.cs

委托

实现方法的参数化,委托是一种引用方法的类型,类似函数指针的集合,为委托分配了多个方法(依序可重复),调用委托会一次调用分配的方法。

委托定义

委托是类,定义了方法的类型,可以将方法当作参数传递,避免了大量if…else…(switch)语句,可扩展性。
委托与函数指针的区别:

安全性:c/c++函数指针只是传递函数地址,无类型安全性;.NET中委托类型安全。与实例关联性:方法通常与类实例关联,委托可以获取类实例信息,从而实现与类实例的关联。函数指针是指针变量,分配在栈中;委托声明是类,类实例化为对象,分配在堆中。委托可以指向不同类中相同类型的方法,函数指针不可以。 委托声明

[修饰符] delegate [返回值类型] [委托名称] ([参数列表])

[修饰符]可选。

委托是一种数据类型,派生于System.Delegate的派生类。

委托应用

Test.cs

using System;class Test{delegate int MyDelegate(int x, int y);//x,y不能省略int Add(int x, int y){return x+y;}static void Main(){Test tc = new Test();MyDelegate md = tc.Add;Console.WriteLine(md(2,3));//等价于md.Invoke(2,3)}}

csc Test.cs

Heater.cs

using System;using System.Threading;class Heater{int temperature;string type = "RealFire 001";string area = "China CQ";public class BoiledEventArgs:EventArgs{public readonly int temperature;public BoiledEventArgs(int temperature){this.temperature = temperature;}}//声明委托delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);//声明事件event BoiledEventHandler Boiled;protected virtual void OnBoiled(BoiledEventArgs e){if(Boiled!=null)Boiled(this, e);}void BoilWater(){for(int i=0;i<=100;i++){temperature = i;if(temperature>95){BoiledEventArgs e = new BoiledEventArgs(temperature);OnBoiled(e);}}}class Alarm{public void Makealert(Object sender, BoiledEventArgs e){Heater heater = (Heater)sender;Console.WriteLine("Alarm:{0}-{1}", heater.area, heater.type);//内部类可以访问外部内私有变量Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}℃了", e.temperature);Console.WriteLine();}}class Display{public static void ShowMsg(Object sender, BoiledEventArgs e){Heater heater = (Heater)sender;Console.WriteLine("Display:{0}-{1}", heater.area, heater.type);//内部类可以访问外部内私有变量Console.WriteLine("Display:水快烧开了,当前温度:{0}℃", e.temperature);Console.WriteLine();Thread.Sleep(1000);}}class Program{static void Main(){Heater heater = new Heater();Alarm alarm = new Alarm();//内部类可以创建私有内部类,访问私有内部类的方法需要publicheater.Boiled = alarm.Makealert;//给事件赋值方法//heater.Boiled += alarm.Makealert;//Boiled为null,与上面等价heater.Boiled += (new Alarm()).Makealert;//匿名对象注册方法heater.Boiled += new BoiledEventHandler(alarm.Makealert);//通过委托对象注册方法heater.Boiled += Display.ShowMsg;//注册静态方法heater.BoilWater();//烧水,自动调用注册过的方法}}}

csc Heater.cs

匿名方法

匿名方法允许一个与委托关联的代码被内联地写入使用委托的位置,可以共享对本地语句包含的方法成员的访问。

delegate(【参数列表】){【代码块】}

Program.cs

using System;using System.Threading;class Program{delegate void DelOutput(string s);static void NamedMethod(string k){Console.WriteLine(k);}static void Main(){DelOutput del = delegate(string j){Console.WriteLine(j);};del.Invoke("匿名方法被调用");Console.WriteLine();del = NamedMethod;del.Invoke("静态方法被调用");Console.WriteLine();}}

csc Program.cs

委托实例

Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;class Delegates{ //创建委托类型 public delegate bool NumberPredicate(int number); static void Main(string[] args){ int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; //生成委托实例 NumberPredicate evenPredicate = IsEven; //利用委托变量调用IsEven Console.WriteLine("Call IsEven using a delegate variable: {0}", evenPredicate(2)); //选出偶数 List evenNumbers = FilterArray(numbers, evenPredicate); //描述并输出 DisplayList("Use IsEven to filter even numbers: ", evenNumbers); //滤过 //选出素数并输出 NumberPredicate primePredicate = IsPrime; List Prime = FilterArray(numbers, primePredicate); DisplayList("Use IsPrime to filter even numbers: ", Prime); } private static List FilterArray(int[] intArray, NumberPredicate predicate){ List numbers = new List(); for(int i = 0; i < intArray.Length; i++) if(predicate(intArray[i])) numbers.Add(intArray[i]); return numbers; } //偶数判断函数 private static bool IsEven(int number){ return (number % 2 == 0); } //判断是否素数 private static bool IsPrime(int number){ if(number <= 1) return false; else for(int i = 2; i <= Math.Sqrt(number); i++) if(number % i == 0)return false; return true; } //列表元素输出 private static void DisplayList(string description, List list){ Console.Write(description); foreach(int number in list) Console.Write(number + " "); Console.WriteLine(); }}

csc Program.cs

事件

引发事件,发生与对象相关事件(对象数据修改,进程完成,服务中断等)时,类将事件通知给用户,引发事件的对象称为事件源或发送者。

事件定义

事件与委托相关,发生事件,产生动作。

事件使用

使用事件步骤:
①创建委托;
②关联委托与事件;
③编写事件处理程序;
④事件处理程序生成委托实例;
⑤订阅事件(委托实例添加到产生事件对象的事件列表中)。

定义事件
先定义委托,后定义事件。

<访问修饰符> event 委托名 事件名;

事件的发布和订阅
通过委托实现事件的发布(执行)和订阅(注册),执行以下步骤:
①定义委托和关联事件;
②发布器中写触发事件的条件(方法、其他事件等);
③订阅器中编写处理事件的方法程序等;
④通过事件订阅处理事件的方法程序。

<事件> += new <事件关联委托>(<处理事件的方法名>);

Program.cs

using System;public delegate void mydelegate();//定义与事件关联的委托类class Mum{//定义事件发布者母亲类public event mydelegate EatEvent;//定义事件public void Cook(){Console.WriteLine("母亲:饭好了,来吃饭。");EatEvent();//触发事件}}class Son{//定义订阅器儿子类public void Eat(){Console.WriteLine("儿子:妈,我写完作业再来。");}}class Father{//定义订阅器父亲类public void Eat(){//事件处理方法Console.WriteLine("母亲:老婆,我来吃饭了。");}}class Program{static void Main(){//事件处理方法Mum mum = new Mum();Father father = new Father();Son son = new Son();mum.EatEvent += new mydelegate(son.Eat);//不能使用=mum.EatEvent += new mydelegate(father.Eat);mum.Cook();}}

csc Program.cs

事件实例

csc Program.cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;public static class Sun{ public static event EventHandler OnRise; //EventHandler 为委托名 public static void Rise(){ Console.WriteLine("太阳从东方升起!"); if(onRise != null) OnRise(null, null); }}public class Cock{ private string _name; public Cock(string name){ _name = name; Sun.onRise += new EventHandler(Sun_OnRise); } private void Sun_OnRise(object sender, EventArgs e){//太阳升起引发公鸡打鸣 Console.WriteLine("公鸡{0}:", _name); Console.WriteLine("雄鸡一声天下白!"); this.Sing(); } public event EventHandler OnSing; public void Sing(){ Console.WriteLine("喔喔喔……"); if(onSing != null) OnSing(this, null); }}public class Host{ private string _name; public Host(string name) { _name = name; } public event EventHandler OnGetup; public void Getup(){ Console.WriteLine("日出而作……"); if (onGetup != null) OnGetup(this, null); } public void Foster(Cock c1){ c1.onSing += new EventHandler(c1_OnSing); } private void c1_OnSing(object sender, EventArgs e){//公鸡打鸣引起主人起床 Console.WriteLine("主人{0}:", _name); Console.WriteLine("闻鸡起舞!"); this.Getup(); }}public class Dog{ private string _name; private Host _owner; public Dog(string name){ _name = name; } public Host Owner{ get { return this._owner; } set{ this._owner = value; Owner.onGetup += new EventHandler(owner_OnGetup); } } private void owner_OnGetup(object sender, EventArgs e){//主人起床引起狗叫 Console.Write("狗 {0}:", _name); Console.WriteLine("汪汪"); }}public class Cat{ private string _name; private Host _owner; public Cat(string name){ _name = name; } public Host Owner{ get { return this._owner; } set{ this._owner = value; Owner.onGetup += new EventHandler(owner_OnGetup); } } private void owner_OnGetup(object sender, EventArgs e){//主人起床引起猫叫 Console.Write("猫 {0}:", _name); Console.WriteLine("喵喵"); }}class Program{ static void Main(string[] args){ Cock cock1 = new Cock("花花"); Host host1 = new Host("祖逖"); Dog dog1 = new Dog("旺财"); Cat cat1 = new Cat("咪咪"); host1.Foster(cock1); dog1.Owner = host1; cat1.Owner = host1; Sun.Rise(); }}

csc Program.cs

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。