一、c#中的特殊数据类型
C#中卓越数据类型有class类型、结构类型、数组类型、枚举类型、集结类型、委托项目、事件、拉姆da表明式、接口类型。
一、c#中的特殊数据类型
C#中特殊数据类型有class类型、结构类型、数组类型、枚举类型、集结类型、委托项目、事件、拉姆da表明式、接口类型。
1、class类型
1、class类型
1.1类定义
class Student : person//继承
{
//默认构造函数,vs IDE中输入ator+tab两下可自动生成构造函数代码段
public Student()
{
//给字段赋值等初始化操作
}
//自定义构造函数,b为可选参数
public Student(int a, string b = 5)
{
//初始化操作
}
public Student(int a)//自定义构造函数
{
//初始化操作
}
//静态构造函数-安全的给静态字段赋值且只能被定义一个(采用普通构造函数每次实例化类对象时静态字段的值会被重置)
static Student{aCuu=0.04}//不允许访问修饰符,不接受参数
//static关键字用来定义静态成员,这些成员只能通过类级别而不是对象引用调用。
//static关键字,静态字段由所有类实例共享
public static double aCuu = 0.04;
public string petName;//字段,最好定义成私有的以保护
public void Name(string name) { }---方法
}
//静态类-只包含静态成员,不能够使用new(分配新内存)关键字来创建类对象-适合做工具类
static class Student { }
1.1类定义
class Student : person//继承
{
//默认构造函数,vs IDE中输入ator+tab两下可自动生成构造函数代码段
public Student()
{
//给字段赋值等初始化操作
}
//自定义构造函数,b为可选参数
public Student(int a, string b = 5)
{
//初始化操作
}
public Student(int a)//自定义构造函数
{
//初始化操作
}
//静态构造函数-安全的给静态字段赋值且只能被定义一个(采用普通构造函数每次实例化类对象时静态字段的值会被重置)
static Student{aCuu=0.04}//不允许访问修饰符,不接受参数
//static关键字用来定义静态成员,这些成员只能通过类级别而不是对象引用调用。
//static关键字,静态字段由所有类实例共享
public static double aCuu = 0.04;
public string petName;//字段,最好定义成私有的以保护
public void Name(string name) { }---方法
}
//静态类-只包含静态成员,不能够使用new(分配新内存)关键字来创建类对象-适合做工具类
static class Student { }
1.二造访修饰符
类型成员隐式私有的,而类是隐式内部的。
private、protected、protected internal访问修饰符能够接纳到嵌套类型上,非嵌套类型只好用public
internal修饰符定义。
public | 可以从对象、派生类、外部其它程序集访问 |
private | 定义类访问 |
protected | 定义类及子类可以访问,外部类无法通过点操作符访问 |
internal | 只能在当前程序集中访问 |
protected internal | 在定义该项的程序集、类及派生类中可用 |
壹.贰造访修饰符
类别成员隐式私有的,而类是隐式内部的。
private、protected、protected internal访问修饰符能够应用到嵌套类型上,非嵌套类型只好用public
internal修饰符定义。
public | 可以从对象、派生类、外部其它程序集访问 |
private | 定义类访问 |
protected | 定义类及子类可以访问,外部类无法通过点操作符访问 |
internal | 只能在当前程序集中访问 |
protected internal | 在定义该项的程序集、类及派生类中可用 |
1.3 this 关键字
提供对当下类实例的走访。
串联构造函数,使类更便于保障和强烈。
class Motorcycle
{
public int driverIntensity;
public string drivername;
//构造函数
public Motorcycle(){}
public Motorcycle(int intensity) : this(intensity, "") { }
public Motorcycle(string name):this(0,name) { }
//所有工作的主构造函数
public Motorcycle(int intensity,string name)
{
//操作
}
}
1.3 this 关键字
提供对当下类实例的访问。
串联构造函数,使类更便于保险和明朗。
class Motorcycle
{
public int driverIntensity;
public string drivername;
//构造函数
public Motorcycle(){}
public Motorcycle(int intensity) : this(intensity, "") { }
public Motorcycle(string name):this(0,name) { }
//所有工作的主构造函数
public Motorcycle(int intensity,string name)
{
//操作
}
}
二、结构类型
布局类型能够看作是轻量级的类类型,可是不能够像类同样持续
struct point
{
//字段
public int x;
//方法
public void Increment()
{
}
}
//创建结构变量
point p1;
p1.x = 5;//需要为每一个共有字段成员赋值
point p2 = new point();
二、结构类型
结构类型能够作为是轻量级的类类型,不过不可能像类一样持续
struct point
{
//字段
public int x;
//方法
public void Increment()
{
}
}
//创建结构变量
point p1;
p1.x = 5;//需要为每一个共有字段成员赋值
point p2 = new point();
3、数组类型
壹组壹致类别的数分部:int[] myInt=new int[3]
int[] myInt=new int[3]{1,2,3} #初始化
3、数组类型
壹组一样类别的数分局:int[] myInt=new int[3]
int[] myInt=new int[3]{1,2,3} #初始化
三.壹 特殊数组
隐式数组 | var a=new[]{1,2,3} |
object数组 | object[] myob=new[3]{1,"string",new DateTime(2017,8,28)} |
多维数组 | int[,] myArray=new int[6,6] |
叁.1 特殊数组
隐式数组 | var a=new[]{1,2,3} |
object数组 | object[] myob=new[3]{1,"string",new DateTime(2017,8,28)} |
多维数组 | int[,] myArray=new int[6,6] |
肆、枚举类型
System.Enum类中蕴藏有一部分对枚举类型操作的方法
enum Emptype:Byte
{
manager=12,//=0,可任意,可不连续
student,
teancher
}
Emptype ee = Emptype.manager;
Enum.GetUnderlyingType(ee.GetType());//返回枚举类型值的数据类型
Console.WriteLine(ee.ToString());//获取枚举名字
Console.WriteLine((Byte)ee);//根据底层类型强制转换获取其数值
Array enumData = Enum.GetValues(ee.GetType());//获取所有枚举值
Console.WriteLine("this enum has {0} nums:", enumData.Length);
Console.WriteLine("name{0};value{1}", enumData.GetValue(1));
四、枚举类型
System.Enum类中蕴涵有局地对枚举类型操作的秘籍
enum Emptype:Byte
{
manager=12,//=0,可任意,可不连续
student,
teancher
}
Emptype ee = Emptype.manager;
Enum.GetUnderlyingType(ee.GetType());//返回枚举类型值的数据类型
Console.WriteLine(ee.ToString());//获取枚举名字
Console.WriteLine((Byte)ee);//根据底层类型强制转换获取其数值
Array enumData = Enum.GetValues(ee.GetType());//获取所有枚举值
Console.WriteLine("this enum has {0} nums:", enumData.Length);
Console.WriteLine("name{0};value{1}", enumData.GetValue(1));
5、集结类型-数据容器
System.Collections与System.Collection.Generic命名空间
轻便数组平日是永世大小的,而集结类本人的尺码是动态的,类似于python中的list类型,繁多集合提供了更加强的花色安全,进行了可观优化,能够以内部存款和储蓄器高效的章程管理所涵盖的数量。
集结可划分为两大门类:非泛型集结和泛型集合
伍、集合类型-数据容器
System.Collections与System.Collection.Generic命名空间
轻巧数组一般是稳固大小的,而集合类本身的尺寸是动态的,类似于python中的list类型,诸多汇聚提供了越来越强的品种安全,实行了中度优化,能够以内部存款和储蓄器高效的法子管理所蕴藏的数额。
集合可分割为两大体系:非泛型集结和泛型集结
五.一泛型会集System.Collections常用类
ArrrayList | 动态大小对象集合,对象按顺序列出 | Ilist/Icollection/IEnumerable/ICloneable |
BitArray | 管理位值的简单数组,位值bool类型 | ICollection/IEnumerable/ICloneable |
Hashtable | 表示键值对的集合 | IDictionary/Icollection/IEnumerable/ICloneable |
Queue | FIFO队列 | ICollection/IEnumerable/ICloneable |
SortedList | 键值对集合按键排序 | IDictionary/Icollection/IEnumerable/ICloneable |
Stack | 后进先出 | ICollection/IEnumerable/ICloneable |
System.Collections中类所扶助的根本接口
ICollection | 为所有非泛型集合定义基本特性(大小、枚举、线程安全) |
ICloneable | 允许实现它的对象向调用者返回它的副本 |
IDictionary | 非泛型集合使用键值对表示其内容 |
IEnumerable | 返回实现了IEnumerable接口的对象 |
IEnumerator | 允许子类型以foreach形式迭代 |
IList | 为顺序列表中的对象提供添加、移除和索引项的行为 |
以身作则代码:
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
//集合:很多数据的一个集合
//数组:长度不可变、类型单一
list.Add(true);
list.Add(1);
list.Add(2);
list.Add("张三");
Person person = new Person();
list.Add(person);
list.Add(new int[] { 1, 2, 3 });
list.AddRange(list);
list.AddRange(new int[] { 234, 23432 });//此种方法可以直接输出
for(int i=0; i<list.Count; i++)
{
if(list[i] is Person )
{
((Person)list[i]).SayKello();
}
else if(list[i] is int[])
{
for(int j=0;j<((int[])list[i]).Length;j++)
{
Console.WriteLine(((int[])list[i])[j]);
}
} //麻烦
else
{
Console.WriteLine(list[i]);
}
}
Console.ReadKey();
//List元素打印出来的是所在类对应的命名空间
}
class Person
{
public void SayKello()
{
Console.Write("你好"+"\r\n");
}
}
}
//其他类的用法类似,有相应的文档
5.1泛型集结System.Collections常用类
ArrrayList | 动态大小对象集合,对象按顺序列出 | Ilist/Icollection/IEnumerable/ICloneable |
BitArray | 管理位值的简单数组,位值bool类型 | ICollection/IEnumerable/ICloneable |
Hashtable | 表示键值对的集合 | IDictionary/Icollection/IEnumerable/ICloneable |
Queue | FIFO队列 | ICollection/IEnumerable/ICloneable |
SortedList | 键值对集合按键排序 | IDictionary/Icollection/IEnumerable/ICloneable |
Stack | 后进先出 | ICollection/IEnumerable/ICloneable |
System.Collections中类所援助的重中之重接口
ICollection | 为所有非泛型集合定义基本特性(大小、枚举、线程安全) |
ICloneable | 允许实现它的对象向调用者返回它的副本 |
IDictionary | 非泛型集合使用键值对表示其内容 |
IEnumerable | 返回实现了IEnumerable接口的对象 |
IEnumerator | 允许子类型以foreach形式迭代 |
IList | 为顺序列表中的对象提供添加、移除和索引项的行为 |
以身作则代码:
class Program
{
static void Main(string[] args)
{
ArrayList list = new ArrayList();
//集合:很多数据的一个集合
//数组:长度不可变、类型单一
list.Add(true);
list.Add(1);
list.Add(2);
list.Add("张三");
Person person = new Person();
list.Add(person);
list.Add(new int[] { 1, 2, 3 });
list.AddRange(list);
list.AddRange(new int[] { 234, 23432 });//此种方法可以直接输出
for(int i=0; i<list.Count; i++)
{
if(list[i] is Person )
{
((Person)list[i]).SayKello();
}
else if(list[i] is int[])
{
for(int j=0;j<((int[])list[i]).Length;j++)
{
Console.WriteLine(((int[])list[i])[j]);
}
} //麻烦
else
{
Console.WriteLine(list[i]);
}
}
Console.ReadKey();
//List元素打印出来的是所在类对应的命名空间
}
class Person
{
public void SayKello()
{
Console.Write("你好"+"\r\n");
}
}
}
//其他类的用法类似,有相应的文档
HashTable示例:
static void Main(string[] args)
{
//键值对集合类似于字典,根据键去找值,就像根据拼音去找汉字
Hashtable ht = new Hashtable();
ht.Add(1,"张三");
ht.Add(2,"小王");
ht.Add(false,"错误的");
for (int i = 0; i < ht.Count; i++)
{
object a = ht[i];
Console.WriteLine(a);
}
//不能全部显示(0和false)
Console.ReadKey();
Console.WriteLine(ht[false]);
//也可以采用foreach循环遍历
foreach (var item in ht.Keys)
{
//C#是一门强类型语言:代码中每一个变量类型必须有明确的定义
//int n = 15;
//string ste = "sfdd";
//bool n5 = true;
//double n6 = 230.23;
//Console.WriteLine(n.GetType());
//Console.WriteLine(ste.GetType());
//Console.WriteLine(n5.GetType());
//Console.WriteLine(n6.GetType());
//Console.ReadKey();
//根据值推断出类型
//var n = 15;
//var ste = "sfdd";
//var n5 = true;
//var n6 = 230.23;
//Console.WriteLine(n.GetType());
//Console.WriteLine(ste.GetType());
//Console.WriteLine(n5.GetType());
//Console.WriteLine(n6.GetType());
//Console.ReadKey();
//var input; 声明var变量的时候必需给它赋值
//input = "人民";
Console.WriteLine(ht[item]);
}
Console.ReadKey();
}
View Code
HashTable示例:
static void Main(string[] args)
{
//键值对集合类似于字典,根据键去找值,就像根据拼音去找汉字
Hashtable ht = new Hashtable();
ht.Add(1,"张三");
ht.Add(2,"小王");
ht.Add(false,"错误的");
for (int i = 0; i < ht.Count; i++)
{
object a = ht[i];
Console.WriteLine(a);
}
//不能全部显示(0和false)
Console.ReadKey();
Console.WriteLine(ht[false]);
//也可以采用foreach循环遍历
foreach (var item in ht.Keys)
{
//C#是一门强类型语言:代码中每一个变量类型必须有明确的定义
//int n = 15;
//string ste = "sfdd";
//bool n5 = true;
//double n6 = 230.23;
//Console.WriteLine(n.GetType());
//Console.WriteLine(ste.GetType());
//Console.WriteLine(n5.GetType());
//Console.WriteLine(n6.GetType());
//Console.ReadKey();
//根据值推断出类型
//var n = 15;
//var ste = "sfdd";
//var n5 = true;
//var n6 = 230.23;
//Console.WriteLine(n.GetType());
//Console.WriteLine(ste.GetType());
//Console.WriteLine(n5.GetType());
//Console.WriteLine(n6.GetType());
//Console.ReadKey();
//var input; 声明var变量的时候必需给它赋值
//input = "人民";
Console.WriteLine(ht[item]);
}
Console.ReadKey();
}
View Code
5.2非泛型会集
绝比较于泛型会集,非泛型集结更为常用,经典的泛型集结平日存在如下问题:
一)频仍的装箱拆箱操作,当数据量过大时会降低程序作用:
.NET包涵2个特殊的Object类,能够承受大肆的数据类型的值,当所传递或所赋值的品类不是三个一定的数据类型时,object类就提供了一种传递参数和赋值的通用方法。赋给object的值必须作为引用类型,并存放砸托管堆中,简言之装箱正是值类型转换为引用类型;拆箱正是援引类型调换为值类型。
值类型:包蕴原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举 (enum)
、结构 (struct)。
引用类型:包涵类、数组、接口、委托、字符串等
一下异样景况需求注意:
隐式转换总会成功的情况 | 显式引用转换可能会抛出异常的情况 |
从派生类到基类 | 从基类到派生类 |
从派生接口到基接口 | 从接口到接口(基接口到派生接口或者俩接口没有关系) |
从类到接口(该类实现了接口) | 从接口到类(该类实现了该接口或该类未封闭) |
从Null到任何类 | 从类到接口(该类未实现该接口且该类未封闭) |
class Program
{
int a = 3;
object ob = a;//装箱操作
int b = (int)ob;//拆箱操作
}
二)类型安全难题,全数的品类都足以转换来object类,在特定的状态下存在项目安全难点。
伍.贰非泛型群集
相相比较于泛型会集,非泛型集合更为常用,杰出的泛型集结常常存在如下难题:
一)频繁的装箱拆箱操作,当数据量过大时会降低程序功用:
.NET包罗三个独特的Object类,能够承受任性的数据类型的值,当所传递或所赋值的类型不是一个一定的数据类型时,object类就提供了1种传递参数和赋值的通用方法。赋给object的值必须作为引用类型,并存放砸托管堆中,简言之装箱正是值类型调换为引用类型;拆箱便是援引类型转变为值类型。
值类型:包涵原类型(Sbyte、Byte、Short、Ushort、Int、Uint、Long、Ulong、Char、Float、Double、Bool、Decimal)、枚举 (enum)
、结构 (struct)。
引用类型:包蕴类、数组、接口、委托、字符串等
一下卓绝情形必要小心:
隐式转换总会成功的情况 | 显式引用转换可能会抛出异常的情况 |
从派生类到基类 | 从基类到派生类 |
从派生接口到基接口 | 从接口到接口(基接口到派生接口或者俩接口没有关系) |
从类到接口(该类实现了接口) | 从接口到类(该类实现了该接口或该类未封闭) |
从Null到任何类 | 从类到接口(该类未实现该接口且该类未封闭) |
class Program
{
int a = 3;
object ob = a;//装箱操作
int b = (int)ob;//拆箱操作
}
二)类型安全难题,全体的等级次序都足以转换来object类,在特定的状态下存在项目安全难点。
5.3泛型会集
只有类、结构、接口和嘱托可以行使泛型,枚举类型不能。
1)System.Collection.Generic命名空间
贰)开端化语法
class Point
{
int x;
int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
class Program
{
static void Main(string[] args)
{
List<Point> myOfpoint = new List<Point>
{
new Point(1,2),
new Point(3,4)
};
}
}
3)List<T>类
常见用法见:http://www.cnblogs.com/AdaLoong/p/5528917.html
四)Stack<T>类—后进先出
含有Push和Pop方法,能够向栈中压入数据或弹出数据,在观望栈时获得的长久是栈顶对象,能够通过调用peek()来展现。
http://www.cnblogs.com/deom/p/5349317.html
5)Queue<T>类—先进先出
http://www.cnblogs.com/jiahuafu/archive/2013/01/05/2845640.html
Dequeue()—移除并回到开头出的靶子;
Enqueue()—在末未增多壹对象;
peek()—重返起头出的靶子可是不移除。
陆)SortedSet<T>类—自动排序
务必通报SortedSet<T>类按照何种方法排序,能够向其构造函数字传送递一个兑现了IComparer<T>泛型接口的参数,比如3个落到实处了该泛型接口的类。
http://blog.sina.com.cn/s/blog_621e24e20100zqmq.html
class sortByage:IComparer<Person>
{
public int Compare(Person firstperson,Person secondperson)
{
if (firstperson.age > secondperson.age)
return 1;
if (firstperson.age < secondperson.age)
return -1;
else
return 0;
}
}
class Person
{
string firstname;
string lastname;
public int age;
public Person(string firstname,string lastname,int age)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
}
static void Main(string[] args)
{
SortedSet<Person> mysortedOfperson = new SortedSet<Person>(new sortByage())
{
new Person("wangming","zhang",112),
new Person("xiaogang","wang",13),
new Person("xiaohong","li",56)
};
//按照年龄排序
foreach (Person p in mysortedOfperson)
{
Console.WriteLine(p.age);
}
Console.ReadKey();
}
7)System.Collections.ObjectModel命名空间
该命名空间也是以泛型为主导
四个比较灵通的类
ObservableCollection<T> | 表示能在添加、移除项或者刷新整个列表时提供通知的动态数据集合 |
ReadOnltObservableCollection<T> | 表示ObservableCollection<T>的只读版本 |
ObservableCollection<T>与List<T>具有一样的骨干接口,不相同的是ObservableCollection<T>达成了名字为CollectionChanged的事件,该事件在丰裕、移除项大概刷新整个列表时接触。
CollectionChanged定义为委托,该信托能够调用壹类格局(第3个参数为object,第一个参数为NotifyCollectionChanged伊夫ntArgs)。
class Program
{
static void Main(string[] args)
{
ObservableCollection<Person> mysortedOfperson = new ObservableCollection<Person>()
{
new Person("wangming","zhang",112),
new Person("xiaogang","wang",13),
new Person("xiaohong","li",56)
};
//按照年龄排序
//绑定collentionchanged事件
mysortedOfperson.CollectionChanged += people_collentionchanged;
mysortedOfperson.Add(new Person("jfoda", "ad", 12));
Console.ReadKey();
}
static void people_collentionchanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//触发事件的行为是什么
Console.WriteLine("Action for this event:{0}", e.Action);
if(e.Action==System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
Console.WriteLine("here are the new item:");
foreach (Person p in e.NewItems)
{
Console.WriteLine(p.ToString());
}
}
}
}
class Person
{
string firstname;
string lastname;
public int age;
public Person(string firstname,string lastname,int age)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
}
5.三泛型群集
只有类、结构、接口和嘱托能够动用泛型,枚举类型不得以。
1)System.Collection.Generic命名空间
2)伊始化语法
class Point
{
int x;
int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
class Program
{
static void Main(string[] args)
{
List<Point> myOfpoint = new List<Point>
{
new Point(1,2),
new Point(3,4)
};
}
}
3)List<T>类
广大用法见:http://www.cnblogs.com/AdaLoong/p/5528917.html
4)Stack<T>类—后进先出
含有Push和Pop方法,可以向栈中压入数据或弹出数据,在旁观栈时得到的千古是栈顶对象,可以经过调用peek()来显示。
http://www.cnblogs.com/deom/p/5349317.html
伍)Queue<T>类—先进先出
http://www.cnblogs.com/jiahuafu/archive/2013/01/05/2845640.html
Dequeue()—移除并赶回发轫出的靶子;
Enqueue()—在末未增添一目的;
peek()—重返开始出的靶子只是不移除。
陆)SortedSet<T>类—自动排序
非得通报SortedSet<T>类根据何种方法排序,能够向其构造函数字传送递贰个贯彻了IComparer<T>泛型接口的参数,举个例子三个得以落成了该泛型接口的类。
http://blog.sina.com.cn/s/blog_621e24e20100zqmq.html
class sortByage:IComparer<Person>
{
public int Compare(Person firstperson,Person secondperson)
{
if (firstperson.age > secondperson.age)
return 1;
if (firstperson.age < secondperson.age)
return -1;
else
return 0;
}
}
class Person
{
string firstname;
string lastname;
public int age;
public Person(string firstname,string lastname,int age)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
}
static void Main(string[] args)
{
SortedSet<Person> mysortedOfperson = new SortedSet<Person>(new sortByage())
{
new Person("wangming","zhang",112),
new Person("xiaogang","wang",13),
new Person("xiaohong","li",56)
};
//按照年龄排序
foreach (Person p in mysortedOfperson)
{
Console.WriteLine(p.age);
}
Console.ReadKey();
}
7)System.Collections.ObjectModel命名空间
该命名空间也是以泛型为骨干
四个相比有效的类
ObservableCollection<T> | 表示能在添加、移除项或者刷新整个列表时提供通知的动态数据集合 |
ReadOnltObservableCollection<T> | 表示ObservableCollection<T>的只读版本 |
ObservableCollection<T>与List<T>具备同样的主干接口,分裂的是ObservableCollection<T>达成了名称为CollectionChanged的事件,该事件在增加、移除项大概刷新整个列表时接触。
CollectionChanged定义为委托,该信托能够调用一类情势(第3个参数为object,第3个参数为NotifyCollectionChanged伊夫ntArgs)。
class Program
{
static void Main(string[] args)
{
ObservableCollection<Person> mysortedOfperson = new ObservableCollection<Person>()
{
new Person("wangming","zhang",112),
new Person("xiaogang","wang",13),
new Person("xiaohong","li",56)
};
//按照年龄排序
//绑定collentionchanged事件
mysortedOfperson.CollectionChanged += people_collentionchanged;
mysortedOfperson.Add(new Person("jfoda", "ad", 12));
Console.ReadKey();
}
static void people_collentionchanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//触发事件的行为是什么
Console.WriteLine("Action for this event:{0}", e.Action);
if(e.Action==System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
Console.WriteLine("here are the new item:");
foreach (Person p in e.NewItems)
{
Console.WriteLine(p.ToString());
}
}
}
}
class Person
{
string firstname;
string lastname;
public int age;
public Person(string firstname,string lastname,int age)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
}
6、委托项目delegate
信托项目用来定义和响应应用程序中的回调,使用回调技师能够应用一个函数重返报告给程序中的另一个函数,使用那种措施,windows开采者能够可以管理按键单击、鼠标移动、菜单选用以及内部存款和储蓄器中四个实体的双向通讯。本质上嘱托是个品种安全的目标,它指向贰个从此会被调用的艺术(恐怕七个方式),可以毫无手工业成立三个thread对象去条用其余thread上的格局,委托项目有两个重视的音讯:
一)它所调用的秘诀和名称
二)该措施的参数(可选)
3)该办法的回来值类型(可选)
六、委托项目delegate
信托项目用来定义和响应应用程序中的回调,使用回调技师能够选拔二个函数再次来到报告给程序中的另三个函数,使用这种办法,windows开垦者能够能够管理按键单击、鼠标移动、菜单选用以及内部存款和储蓄器中三个实体的双向通讯。本质上嘱托是个类型安全的对象,它指向一个后头会被调用的主意(可能五个办法),能够毫不手工业创造3个thread对象去条用其它thread上的章程,委托项目有几个重大的音讯:
一)它所调用的法子和称号
二)该情势的参数(可选)
三)该措施的归来值类型(可选)
陆.1、委托项目标定义
public delegate int BinaryOp(int x,int y)
选用delegate关键字,就直接创制了贰个类,那一个类是“MulticastDelegate”,下表展现了具有寄托对象都某个大旨成员。
例1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托简例
{
public delegate int BinaryOp(int x, int y);
//创建一个包含委托指向方法的类
public class SimpleMath
{
public int Add(int x, int y)
{
return x + y;
}
}
class Program
{
//显示委托对象所维护的方法名称及对应的类名称
static void DisplayDelegateInfo(Delegate delObj)
{
//输出委托调用列表中每个成员的名称
foreach (Delegate d in delObj.GetInvocationList())
{
Console.WriteLine("Method name:{0}", d.Method);
Console.WriteLine("Type name:{0}", d.Target);
}
Console.ReadKey();
}
static void Main(string[] args)
{
//实例化一个委托对象
BinaryOp bp = new BinaryOp(new SimpleMath().Add);//指向的是非静态方法要生成实例
//BinaryOp bp = new BinaryOp(SimpleMath.Add);//指向的是静态方法则不需要,只需给出内存地址即可
Console.WriteLine("10+10={0}", bp(10, 10));
Console.ReadKey();
DisplayDelegateInfo(bp);
}
}
}
6.1、委托项目标概念
public delegate int BinaryOp(int x,int y)
使用delegate关键字,就直接创建了叁个类,这一个类是“MulticastDelegate”,下表展现了独具寄托对象都有些大旨成员。
例1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托简例
{
public delegate int BinaryOp(int x, int y);
//创建一个包含委托指向方法的类
public class SimpleMath
{
public int Add(int x, int y)
{
return x + y;
}
}
class Program
{
//显示委托对象所维护的方法名称及对应的类名称
static void DisplayDelegateInfo(Delegate delObj)
{
//输出委托调用列表中每个成员的名称
foreach (Delegate d in delObj.GetInvocationList())
{
Console.WriteLine("Method name:{0}", d.Method);
Console.WriteLine("Type name:{0}", d.Target);
}
Console.ReadKey();
}
static void Main(string[] args)
{
//实例化一个委托对象
BinaryOp bp = new BinaryOp(new SimpleMath().Add);//指向的是非静态方法要生成实例
//BinaryOp bp = new BinaryOp(SimpleMath.Add);//指向的是静态方法则不需要,只需给出内存地址即可
Console.WriteLine("10+10={0}", bp(10, 10));
Console.ReadKey();
DisplayDelegateInfo(bp);
}
}
}
例2
//声明委托
public delegate void Mydel();
public delegate void Mydel2(int num1, int num2);
public delegate string Mydel3(string s);
//声明委托用于演示匿名方法
public delegate string ProcessString(string S);
class Program
{
static void Main(string[] args)
{
TestDel t = new TestDel();
#region 简单实例化委托与调用委托
Console.WriteLine("------以下是简单使用委托演示----");
t.MyMethod();
//实例化委托,用一个方法实例化
//该方法签名要与委托签名一致
Mydel del0 = new Mydel(t.MyMethod);
//调用委托
del0();
//另一种实例化方法
Mydel del1 = t.MyMethod;
del1();
//用静态方法进行实例化
del1 = TestDel.MyStaticMethod;
del1();
//以下代码效果相同
//类TestDel中重载了多种MyMethod方法,委托自动识别一致参数类型的方法
Mydel2 del2 = new Mydel2(t.MyMethod);
del2(10,20);
Mydel2 del121 = t.MyMethod;
del121(10, 20);
Mydel3 del3 = new Mydel3(t.MyMethod);
del3("adfa");
#endregion
#region 匿名实例化weit
Console.WriteLine("-----以下是匿名调用委托--");
//用匿名方法实例化委托,不需函数名,直接就是参数+函数体
ProcessString p = delegate(string inputString)
{
return inputString.ToUpper();
};
//通过委托调用匿名方法
Console.WriteLine(p("wefewe"));
#endregion
#region 委托多播演示
Console.WriteLine("---------以下是多播演示--------");
Mydel mydel1 = t.MyMethod;
Mydel mydel2 = t.MyMethod2;
Mydel mydel3 = TestDel.MyMethod3;
//委托类型必须一致才能相加
Mydel allmydel = mydel1 + mydel2 + mydel3;
allmydel();
allmydel -= mydel3;
allmydel();
#endregion
#region 委托作为参数演示
Console.WriteLine("-------以下委托作为参数演示--------");
Mydel3 paraMydel3 = t.MyMethod;
TestDel.MyParamMethod("aaa", paraMydel3);
#endregion
#region 委托作为返回值
Console.WriteLine("----以下委托作为返回值演示-----");
//returnMydel指向ReturnMyMethod的返回值
Mydel3 returnMydel = t.ReturnMyMethod();
//returnMydel1指向t.MyMethod
Mydel3 returnMydel1 = t.MyMethod;
Console.WriteLine(returnMydel("sssssss"));
#endregion
}
}
public class TestDel
{
#region 普通方法
public static void MyStaticMethod()
{
Console.WriteLine("My Static Method");
}
public void MyMethod()
{
Console.WriteLine("MyMethod");
}
public void MyMethod2()
{
Console.WriteLine("My Method 22222222222");
}
public static void MyMethod3()
{
Console.WriteLine("My Method 3333333333333");
}
public void MyMethod(int num1, int num2)
{
Console.WriteLine(num1 + num2);
}
public string MyMethod(string s)
{
return s.ToUpper();
}
#endregion
/// <summary>
/// 委托作为方法参数
/// </summary>
/// <param name="s"></param>
/// <param name="del3"></param>
public static void MyParamMethod(string s, Mydel3 del3)
{
Console.WriteLine(del3(s));
}
/// <summary>
/// 委托作为返回值
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public Mydel3 ReturnMyMethod()
{
///返回符合委托规范的方法
return MyMethod;
}
}
View Code
例2
//声明委托
public delegate void Mydel();
public delegate void Mydel2(int num1, int num2);
public delegate string Mydel3(string s);
//声明委托用于演示匿名方法
public delegate string ProcessString(string S);
class Program
{
static void Main(string[] args)
{
TestDel t = new TestDel();
#region 简单实例化委托与调用委托
Console.WriteLine("------以下是简单使用委托演示----");
t.MyMethod();
//实例化委托,用一个方法实例化
//该方法签名要与委托签名一致
Mydel del0 = new Mydel(t.MyMethod);
//调用委托
del0();
//另一种实例化方法
Mydel del1 = t.MyMethod;
del1();
//用静态方法进行实例化
del1 = TestDel.MyStaticMethod;
del1();
//以下代码效果相同
//类TestDel中重载了多种MyMethod方法,委托自动识别一致参数类型的方法
Mydel2 del2 = new Mydel2(t.MyMethod);
del2(10,20);
Mydel2 del121 = t.MyMethod;
del121(10, 20);
Mydel3 del3 = new Mydel3(t.MyMethod);
del3("adfa");
#endregion
#region 匿名实例化weit
Console.WriteLine("-----以下是匿名调用委托--");
//用匿名方法实例化委托,不需函数名,直接就是参数+函数体
ProcessString p = delegate(string inputString)
{
return inputString.ToUpper();
};
//通过委托调用匿名方法
Console.WriteLine(p("wefewe"));
#endregion
#region 委托多播演示
Console.WriteLine("---------以下是多播演示--------");
Mydel mydel1 = t.MyMethod;
Mydel mydel2 = t.MyMethod2;
Mydel mydel3 = TestDel.MyMethod3;
//委托类型必须一致才能相加
Mydel allmydel = mydel1 + mydel2 + mydel3;
allmydel();
allmydel -= mydel3;
allmydel();
#endregion
#region 委托作为参数演示
Console.WriteLine("-------以下委托作为参数演示--------");
Mydel3 paraMydel3 = t.MyMethod;
TestDel.MyParamMethod("aaa", paraMydel3);
#endregion
#region 委托作为返回值
Console.WriteLine("----以下委托作为返回值演示-----");
//returnMydel指向ReturnMyMethod的返回值
Mydel3 returnMydel = t.ReturnMyMethod();
//returnMydel1指向t.MyMethod
Mydel3 returnMydel1 = t.MyMethod;
Console.WriteLine(returnMydel("sssssss"));
#endregion
}
}
public class TestDel
{
#region 普通方法
public static void MyStaticMethod()
{
Console.WriteLine("My Static Method");
}
public void MyMethod()
{
Console.WriteLine("MyMethod");
}
public void MyMethod2()
{
Console.WriteLine("My Method 22222222222");
}
public static void MyMethod3()
{
Console.WriteLine("My Method 3333333333333");
}
public void MyMethod(int num1, int num2)
{
Console.WriteLine(num1 + num2);
}
public string MyMethod(string s)
{
return s.ToUpper();
}
#endregion
/// <summary>
/// 委托作为方法参数
/// </summary>
/// <param name="s"></param>
/// <param name="del3"></param>
public static void MyParamMethod(string s, Mydel3 del3)
{
Console.WriteLine(del3(s));
}
/// <summary>
/// 委托作为返回值
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public Mydel3 ReturnMyMethod()
{
///返回符合委托规范的方法
return MyMethod;
}
}
View Code
陆.二应用委托发送对象通告状态
类似于通过回调函数重回状态音信
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
public class Car
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public Car() { }
public Car(string name,int currentspeed,int maxspeed=100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托类型
public delegate void CarEngineHandler(string msdForCar);
//定义每个委托类型的成员变量
private CarEngineHandler listOfhandlers;
//向调用者添加注册函数
public void RegisterWithCarEngine(CarEngineHandler methodTocall)
{
if (listOfhandlers == null)
listOfhandlers = methodTocall;
else
listOfhandlers += methodTocall;//支持多路广播
}
//实现Accelerate()方法
public void Accelerate(int delta)
{
if(carIsdead)
{
if(listOfhandlers!=null)
{
listOfhandlers("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if(5==(MaxSpeed-CurentSpeed) && listOfhandlers != null)
{
listOfhandlers("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//首先创建一个car对象
Car mycar = new Car("xiaowang",10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换语句---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for(int i=0;i<6;i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
//要传入事件的方法
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
static void CallMeHere(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
}
}
陆.二使用委托发送对象文告状态
类似于经过回调函数重回状态音讯
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
public class Car
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public Car() { }
public Car(string name,int currentspeed,int maxspeed=100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托类型
public delegate void CarEngineHandler(string msdForCar);
//定义每个委托类型的成员变量
private CarEngineHandler listOfhandlers;
//向调用者添加注册函数
public void RegisterWithCarEngine(CarEngineHandler methodTocall)
{
if (listOfhandlers == null)
listOfhandlers = methodTocall;
else
listOfhandlers += methodTocall;//支持多路广播
}
//实现Accelerate()方法
public void Accelerate(int delta)
{
if(carIsdead)
{
if(listOfhandlers!=null)
{
listOfhandlers("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if(5==(MaxSpeed-CurentSpeed) && listOfhandlers != null)
{
listOfhandlers("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//首先创建一个car对象
Car mycar = new Car("xiaowang",10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换语句---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for(int i=0;i<6;i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
//要传入事件的方法
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
static void CallMeHere(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
}
}
六.二兑现多路广播—见陆.1
6.2完毕多路广播—见陆.1
陆.3泛型委托
泛型参数
public delegate void MyDelegate<T>(T
mycan);——-对应一类函数
泛型Action<>和Func<>委托——框架内置的嘱托
泛型Action:能够针对多至十四个参数并回到void的点子,须要制定各样参数的求实项目。
Func<>委托:可以本着多至15个参数并且存有自定义重回值。
Func<int,int,int> functarget=new Func<int,int,int>(Add);
Add中本有三个参数,Func<int,int,int>最后一个参数是再次回到值。
六.三泛型委托
泛型参数
public delegate void MyDelegate<T>(T
mycan);——-对应一类函数
泛型Action<>和Func<>委托——框架内置的寄托
泛型Action:能够针对多至17个参数并重返void的点子,需求制定各类参数的切切实实项目。
Func<>委托:能够本着多至16个参数并且有所自定义重回值。
Func<int,int,int> functarget=new Func<int,int,int>(Add);
Add中本有三个参数,Func<int,int,int>最终叁个参数是重临值。
7、事件
event关键字在变已管理的时候,它会活动的提供注册和撤回方法以及任何须要的寄托项目成员变量,那个成员变量是私家的,不能够从出发事件的目标访问。
概念事件:
一)定义委托项目—-事件触发时要调用的诀窍;
贰)用相关委托注解那几个事件—-使用event关键字。
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
public class Car
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public Car() { }
public Car(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托类型
public delegate void CarEngineHandler(string msdForCar);
//定义每个委托类型的成员变量
private CarEngineHandler listOfhandlers;
//向调用者添加注册函数
public void RegisterWithCarEngine(CarEngineHandler methodTocall)
{
if (listOfhandlers == null)
listOfhandlers = methodTocall;
else
listOfhandlers += methodTocall;//支持多路广播
}
//实现Accelerate()方法
public void Accelerate(int delta)
{
if (carIsdead)
{
if (listOfhandlers != null)
{
listOfhandlers("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && listOfhandlers != null)
{
listOfhandlers("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
public class newCar
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public newCar() { }
public newCar(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托用来与car的时间协作
public delegate void CarEngineNewHandles(string msg);
//汽车可以发送的事件
public event CarEngineNewHandles Exploded;
public event CarEngineNewHandles AbouttoBlow;
public void NewAccelerate(int delta)
{
if (carIsdead)
{
if (Exploded != null)
{
Exploded("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && AbouttoBlow != null)
{
AbouttoBlow("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//////////////////////////////////////////////////////////////////////////使用委托回调
//首先创建一个car对象
Car mycar = new Car("xiaowang", 10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换的---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for (int i = 0; i < 6; i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////// 使用事件回调
//调用者监听传入的事件
///先要使用+=h和-=注册和删除事件
newCar c1 = new newCar("wangming", 30);
//注册事件处理程序
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAboutToBlow);
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAmostAboutToBlow);
newCar.CarEngineNewHandles d = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c1.Exploded += d;
for (int i = 0; i < 6; i++)
{
c1.NewAccelerate(30);
Console.ReadLine();
}
///使用方法组转换简化
newCar c2 = new newCar("wangming", 30);
//注册事件处理程序
c2.AbouttoBlow += CarIsAboutToBlow;
c2.AbouttoBlow += CarIsAmostAboutToBlow;
newCar.CarEngineNewHandles d2 = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c2.Exploded += d2;
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
public static void CarIsAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
public static void CarIsAmostAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
}
}
public class newCar
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public newCar() { }
public newCar(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托用来与car的时间协作
public delegate void CarEngineNewHandles(string msg);
//汽车可以发送的事件
public event CarEngineNewHandles Exploded;
public event CarEngineNewHandles AbouttoBlow;
public void NewAccelerate(int delta)
{
if (carIsdead)
{
if (Exploded != null)
{
Exploded("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && AbouttoBlow != null)
{
AbouttoBlow("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//////////////////////////////////////////////////////////////////////////使用委托回调
//首先创建一个car对象
Car mycar = new Car("xiaowang", 10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换的---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for (int i = 0; i < 6; i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////// 使用事件回调
//调用者监听传入的事件
///先要使用+=h和-=注册和删除事件
newCar c1 = new newCar("wangming", 30);
//注册事件处理程序
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAboutToBlow);
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAmostAboutToBlow);
newCar.CarEngineNewHandles d = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c1.Exploded += d;
for (int i = 0; i < 6; i++)
{
c1.NewAccelerate(30);
Console.ReadLine();
}
///使用方法组转换简化
newCar c2 = new newCar("wangming", 30);
//注册事件处理程序
c2.AbouttoBlow += CarIsAboutToBlow;
c2.AbouttoBlow += CarIsAmostAboutToBlow;
newCar.CarEngineNewHandles d2 = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c2.Exploded += d2;
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
public static void CarIsAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
public static void CarIsAmostAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
}
}
View Code
从上边包车型客车事例也能够观察,手工定义二个信托对象调用的点子显的略微麻烦,不会相当受应接,能够在实行注册时之间将多少个委托与一段代码相关联———–无名方法。
以身作则代码入下:
//注册事件处理程序作为匿名方法
c3.AbouttoBlow += delegate (string msg)
{
Console.WriteLine("匿名委托返回消息{0}", msg);
Console.ReadKey();
};
c3.Exploded += delegate (string msg)
{
Console.WriteLine("feedback information:{0}", msg);
Console.ReadLine();
};
for (int i = 0; i < 6; i++)
{
c3.NewAccelerate(5);
}
7、事件
event关键字在变已管理的时候,它会活动的提供注册和收回方法以及别的必要的嘱托项目成员变量,这几个成员变量是个人的,无法从出发事件的靶子访问。
概念事件:
1)定义委托项目—-事件触发时要调用的方式;
2)用相关委托评释那些事件—-使用event关键字。
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
namespace 委托通知
{
//使用委托来定义car类,他可以通知外部实体当前引擎状态
/// <summary>
/// (1)定义将通知发送给调用者的委托类型
/// (2)声明car类中每个委托类型的成员变量
/// (3)在car上创建副主函数使得调用者能指定由委托成员变量保存的方法
/// (4)修改Accelerate()方法以在适当的情形下调用委托的调用列表
/// </summary>
public class Car
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public Car() { }
public Car(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托类型
public delegate void CarEngineHandler(string msdForCar);
//定义每个委托类型的成员变量
private CarEngineHandler listOfhandlers;
//向调用者添加注册函数
public void RegisterWithCarEngine(CarEngineHandler methodTocall)
{
if (listOfhandlers == null)
listOfhandlers = methodTocall;
else
listOfhandlers += methodTocall;//支持多路广播
}
//实现Accelerate()方法
public void Accelerate(int delta)
{
if (carIsdead)
{
if (listOfhandlers != null)
{
listOfhandlers("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && listOfhandlers != null)
{
listOfhandlers("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
public class newCar
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public newCar() { }
public newCar(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托用来与car的时间协作
public delegate void CarEngineNewHandles(string msg);
//汽车可以发送的事件
public event CarEngineNewHandles Exploded;
public event CarEngineNewHandles AbouttoBlow;
public void NewAccelerate(int delta)
{
if (carIsdead)
{
if (Exploded != null)
{
Exploded("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && AbouttoBlow != null)
{
AbouttoBlow("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//////////////////////////////////////////////////////////////////////////使用委托回调
//首先创建一个car对象
Car mycar = new Car("xiaowang", 10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换的---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for (int i = 0; i < 6; i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////// 使用事件回调
//调用者监听传入的事件
///先要使用+=h和-=注册和删除事件
newCar c1 = new newCar("wangming", 30);
//注册事件处理程序
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAboutToBlow);
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAmostAboutToBlow);
newCar.CarEngineNewHandles d = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c1.Exploded += d;
for (int i = 0; i < 6; i++)
{
c1.NewAccelerate(30);
Console.ReadLine();
}
///使用方法组转换简化
newCar c2 = new newCar("wangming", 30);
//注册事件处理程序
c2.AbouttoBlow += CarIsAboutToBlow;
c2.AbouttoBlow += CarIsAmostAboutToBlow;
newCar.CarEngineNewHandles d2 = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c2.Exploded += d2;
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
public static void CarIsAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
public static void CarIsAmostAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
}
}
public class newCar
{
//内部状态数据
public int CurentSpeed;
public int MaxSpeed;
public string name;
//汽车能不能用
private bool carIsdead;
//类构造函数
public newCar() { }
public newCar(string name, int currentspeed, int maxspeed = 100)
{
this.name = name;
this.CurentSpeed = currentspeed;
this.MaxSpeed = maxspeed;
}
//定义委托用来与car的时间协作
public delegate void CarEngineNewHandles(string msg);
//汽车可以发送的事件
public event CarEngineNewHandles Exploded;
public event CarEngineNewHandles AbouttoBlow;
public void NewAccelerate(int delta)
{
if (carIsdead)
{
if (Exploded != null)
{
Exploded("sorry,this car is dead");
}
}
else
{
CurentSpeed += delta;
//不能超过最大速度
if (5 == (MaxSpeed - CurentSpeed) && AbouttoBlow != null)
{
AbouttoBlow("this speed is nearly to the maxspeed");
}
if (CurentSpeed > MaxSpeed)
{
carIsdead = true;
}
else
Console.WriteLine("current speed:{0}", CurentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
//////////////////////////////////////////////////////////////////////////使用委托回调
//首先创建一个car对象
Car mycar = new Car("xiaowang", 10);
//现在告诉汽车他想要向我们发送信息是应该调用哪个方法
mycar.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
//方法组转换的---传递与委托类型一致的函数
//mycar.RegisterWithCarEngine(CallMeHere);
//加速,触发事件
Console.WriteLine("*******speed up********");
for (int i = 0; i < 6; i++)
{
mycar.Accelerate(20);
Console.ReadKey();
}
////////////////////////////////////////////////////////////////////////// 使用事件回调
//调用者监听传入的事件
///先要使用+=h和-=注册和删除事件
newCar c1 = new newCar("wangming", 30);
//注册事件处理程序
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAboutToBlow);
c1.AbouttoBlow += new newCar.CarEngineNewHandles(CarIsAmostAboutToBlow);
newCar.CarEngineNewHandles d = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c1.Exploded += d;
for (int i = 0; i < 6; i++)
{
c1.NewAccelerate(30);
Console.ReadLine();
}
///使用方法组转换简化
newCar c2 = new newCar("wangming", 30);
//注册事件处理程序
c2.AbouttoBlow += CarIsAboutToBlow;
c2.AbouttoBlow += CarIsAmostAboutToBlow;
newCar.CarEngineNewHandles d2 = new newCar.CarEngineNewHandles(OnCarEngineEvent);
c2.Exploded += d2;
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("feedback information:{0}", msg);
}
public static void CarIsAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
public static void CarIsAmostAboutToBlow(string msg)
{
Console.WriteLine("car is about to blow");
}
}
}
View Code
从上边的例证也足以观望,手工定义一个委托对象调用的不二等秘书技显的略微麻烦,不会深受迎接,能够在实践注册时之间将1个寄托与1段代码相关联———–无名方法。
以身作则代码入下:
//注册事件处理程序作为匿名方法
c3.AbouttoBlow += delegate (string msg)
{
Console.WriteLine("匿名委托返回消息{0}", msg);
Console.ReadKey();
};
c3.Exploded += delegate (string msg)
{
Console.WriteLine("feedback information:{0}", msg);
Console.ReadLine();
};
for (int i = 0; i < 6; i++)
{
c3.NewAccelerate(5);
}
8、Lambda表达式
lambda表明式本质上是用更简便易行的不2法门写匿超情势,首先定义三个参数列表,”=>”标志紧随其后,然后正是处理那么些参数的言辞。
ArgumentsToProcess=>StatementsToProcessThem;参数类型能够是显式的也得以是隐式的。
namespace Lambda表达式
{
class Program
{
static void Main(string[] args)
{
TraditionalDelegateSyntax();
}
static void TraditionalDelegateSyntax()
{
//创建整数列表
List<int> list = new List<int>();
list.AddRange(new int[] { 20, 1, 4, 8, 444, 8 });
////使用传统委托方法调用FindAll()
//Predicate<int> callback = new Predicate<int>(IsEvenNumber);
//List<int> evennumbers = list.FindAll(callback);
//foreach (int evennum in evennumbers)
//{
// Console.WriteLine("{0}\t", evennum);
//}
//Console.ReadKey();
//////////////////////////////////////////////////////////////////////////
//采用匿名方法
//List<int> evennumbers = list.FindAll(delegate (int num)
//{
// return (num % 2 == 0);
//});
//foreach (int evennum in evennumbers)
//{
// Console.WriteLine("{0}\t", evennum);
//}
//////////////////////////////////////////////////////////////////////////
//采用Lamada表达式
List<int> evennumbers = list.FindAll(num=>(num%2)==0);
//运行时被编译成了上述匿名方法
foreach (int evennum in evennumbers)
{
Console.WriteLine("{0}\t", evennum);
}
Console.ReadKey();
}
static bool IsEvenNumber(int num)
{
//这是个偶数
return (num % 2 == 0);
}
}
}
8、Lambda表达式
lambda表明式本质上是用更简便易行的格局写无名情势,首先定义1个参数列表,”=>”标识紧随其后,然后就是拍卖那个参数的口舌。
ArgumentsToProcess=>StatementsToProcessThem;参数类型能够是显式的也得以是隐式的。
namespace Lambda表达式
{
class Program
{
static void Main(string[] args)
{
TraditionalDelegateSyntax();
}
static void TraditionalDelegateSyntax()
{
//创建整数列表
List<int> list = new List<int>();
list.AddRange(new int[] { 20, 1, 4, 8, 444, 8 });
////使用传统委托方法调用FindAll()
//Predicate<int> callback = new Predicate<int>(IsEvenNumber);
//List<int> evennumbers = list.FindAll(callback);
//foreach (int evennum in evennumbers)
//{
// Console.WriteLine("{0}\t", evennum);
//}
//Console.ReadKey();
//////////////////////////////////////////////////////////////////////////
//采用匿名方法
//List<int> evennumbers = list.FindAll(delegate (int num)
//{
// return (num % 2 == 0);
//});
//foreach (int evennum in evennumbers)
//{
// Console.WriteLine("{0}\t", evennum);
//}
//////////////////////////////////////////////////////////////////////////
//采用Lamada表达式
List<int> evennumbers = list.FindAll(num=>(num%2)==0);
//运行时被编译成了上述匿名方法
foreach (int evennum in evennumbers)
{
Console.WriteLine("{0}\t", evennum);
}
Console.ReadKey();
}
static bool IsEvenNumber(int num)
{
//这是个偶数
return (num % 2 == 0);
}
}
}
9、接口
接口是一组抽象成员的命名会集,由接口定义的某部特定成员依赖于它所模拟的合适行为。.NET基础库中提供了几百个预约义的接口类型,由种种型和组织达成。 与抽象类不一样,接口只可以分包抽象成员,由于C#中类不支持多种承继,1个父类定义的架空成员只好被其派生类承袭,不过大型系统中支出除了Object之外未有集体父类的几个档期的顺序结构很宽泛,那样就不可能配备多档期的顺序结构协理一样的多态接口,接口类型消除了那一标题,它能够被此外档次结构。任何命名空间或任何程序集中的别样类或组织来兑现,那样接口就有了较高的多态性。
1)不能够向类和协会同样分配项目:
Ipointy p=new Ipointy()
贰)落成接口是个要”要么全要要么全体绝不”的命题,即帮忙项目无法选择完结怎么着成员。
interface IPoint
{
//接口定义
//1)不指定访问修饰符(默认隐式共有、抽象)
//2)不能实现
// byte GetNumofPoint();
//只读属性
byte Points{ get; }
}
//实现接口时要么全要,要么全不要
class Triangle:Object,IPoint
{ //...
public byte Points
{
get { return 3; }
}
}
class Program
{
static void Main(string[] args)
{
//在对象级别调用接口成员
Triangle triangle = new Triangle();
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
}
9、接口
接口是1组抽象成员的命名集结,由接口定义的某部特定成员依赖于它所模拟的相当行为。.NET基础库中提供了几百个预约义的接口类型,由各样型和布局达成。 与抽象类区别,接口只好分包抽象成员,由于C#中类不扶助多种承袭,2个父类定义的空洞成员只可以被其派生类承袭,不过大型系统中支出除了Object之外未有国有父类的多少个等级次序结构很宽泛,那样就不可能配备多等级次序结构扶助一样的多态接口,接口类型消除了那1主题素材,它能够被其余档次结构。任何命名空间或别的程序聚集的其他类或结构来得以完成,那样接口就有了较高的多态性。
一)不可能向类和组织同样分配项目:
Ipointy p=new Ipointy()
2)完成接口是个要”要么全要要么全部不要”的命题,即协理项目不能够取舍落成怎么样成员。
interface IPoint
{
//接口定义
//1)不指定访问修饰符(默认隐式共有、抽象)
//2)不能实现
// byte GetNumofPoint();
//只读属性
byte Points{ get; }
}
//实现接口时要么全要,要么全不要
class Triangle:Object,IPoint
{ //...
public byte Points
{
get { return 3; }
}
}
class Program
{
static void Main(string[] args)
{
//在对象级别调用接口成员
Triangle triangle = new Triangle();
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
}
九.一哪些推断3个项目是不是帮忙1个点名接口
1)使用显式强制转变。
static void Main(string[] args)
{
//在对象级别调用接口成员
Triangle triangle = new Triangle();
try
{
IPoint point = null;
point = (IPoint)triangle;
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
}
2)as关键字
IPoint point = null;
point = triangle as IPoint;
3)is关键字
//在对象级别调用接口成员
Triangle triangle = new Triangle();
try
{
if (triangle is IPoint)
{
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
玖.一哪些判定三个类型是还是不是辅助一个点名接口
一)使用显式强制调换。
static void Main(string[] args)
{
//在对象级别调用接口成员
Triangle triangle = new Triangle();
try
{
IPoint point = null;
point = (IPoint)triangle;
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
}
2)as关键字
IPoint point = null;
point = triangle as IPoint;
3)is关键字
//在对象级别调用接口成员
Triangle triangle = new Triangle();
try
{
if (triangle is IPoint)
{
Console.WriteLine(triangle.Points);
Console.ReadKey();
}
}
catch (InvalidCastException e)
{
Console.WriteLine(e.Message);
}
玖.二接口作为参数
interface IPoint
{
//接口定义
//1)不指定访问修饰符(默认隐式共有、抽象)
//2)不能实现
string GetNumofName();
//只读属性
//byte Points{ get; }
}
//实现接口时要么全要,要么全不要
class Triangle : Object, IPoint
{ //...
public string GetNumofName()
{
return "i am Triangle ";
}
}
class Rect : Object, IPoint
{ //...
public string GetNumofName()
{
return "i am Rect";
}
}
class Program
{
static public string sayname(IPoint p)
{
return p.GetNumofName();
}
static void Main(string[] args)
{
//在对象级别调用接口成员
//Triangle triangle = new Triangle();
//try
//{
// if (triangle is IPoint)
// {
// Console.WriteLine(triangle.Points);
// Console.ReadKey();
// }
//}
//catch (InvalidCastException e)
//{
// Console.WriteLine(e.Message);
//}
object[] obj = { new Triangle(), new Rect() };
for (int i = 0; i < obj.Length; i++)
{
if (obj[i] is IPoint)
{
IPoint p = (IPoint)obj[i];
Console.WriteLine(sayname(p));
}
}
Console.ReadKey();
}
}
View Code
看似的经过as/is关键字的施用,接口也能够看作重临值。
九.二接口作为参数
interface IPoint
{
//接口定义
//1)不指定访问修饰符(默认隐式共有、抽象)
//2)不能实现
string GetNumofName();
//只读属性
//byte Points{ get; }
}
//实现接口时要么全要,要么全不要
class Triangle : Object, IPoint
{ //...
public string GetNumofName()
{
return "i am Triangle ";
}
}
class Rect : Object, IPoint
{ //...
public string GetNumofName()
{
return "i am Rect";
}
}
class Program
{
static public string sayname(IPoint p)
{
return p.GetNumofName();
}
static void Main(string[] args)
{
//在对象级别调用接口成员
//Triangle triangle = new Triangle();
//try
//{
// if (triangle is IPoint)
// {
// Console.WriteLine(triangle.Points);
// Console.ReadKey();
// }
//}
//catch (InvalidCastException e)
//{
// Console.WriteLine(e.Message);
//}
object[] obj = { new Triangle(), new Rect() };
for (int i = 0; i < obj.Length; i++)
{
if (obj[i] is IPoint)
{
IPoint p = (IPoint)obj[i];
Console.WriteLine(sayname(p));
}
}
Console.ReadKey();
}
}
View Code
看似的经过as/is关键字的利用,接口也能够看成再次来到值。
玖.叁接口数组
接口数组能够包蕴落成了该接口的别的类照旧协会,不论相关不相干。
IPoint[]={new triangle(),new Tree(),new Rect()}
玖.三接口数组
接口数组能够分包完毕了该接口的别的类依旧组织,不论相关不相干。
IPoint[]={new triangle(),new Tree(),new Rect()}
玖.四接口的档次结构
一)接口能够持续,承接后假如一个类达成了该接口,则该接口承接的接口成员也需求被达成,同时接口也支撑二种接续,若分裂接口存在命名争执,能够通过显式接口消除争辩。
九.四接口的等级次序结构
一)接口能够承接,承接后1旦三个类实现了该接口,则该接口承继的接口成员也急需被实现,同时接口也支撑各种一连,若差别接口存在命名争辩,能够透过显式接口化解抵触。