委托与事件
引用面试题来说下委托与事件
C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的指针。
委托和事件没有可比性,因为委托是类型,事件是对象,下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。事件是用来阉割委托实例的,类比用一个自定义类阉割List。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能= 。加分的补充回答:事件内部就是一个private的委托和add、remove两个方法
文件操作:
第一步:声明一个文件流
FileStream fs=new FileStream(ofd.FileName,)
第二步:创建读取器
委托是一种数据类型
就像类一样,类也是一种数据类型
类使用之前需要定义一个类public class...
委托使用之前也需要定义一个委托public delegate....
类定义好后使用时需要声明类的变量,然后new一个类的对象
委托定义好后,使用时,也需要
什么时候用委托,为什么要用委托
当需要保存一个方法的时候使用委托,当要再程序中把方法本身作为参数传递时使用委托。
在程序运行中 有时候要传入一个方法,时这时要需要委托
定义一个委托注意:
1.委托的返回值类型,取决于将来要保存的方法是否有返回值类型
2.委托有没有参数,取决于将来要保存的方法是否有参数及参数的个数与类型
3.委托就像一个没有任何实现的方法一样,以"分号"结尾
4.定义委托需要关键字delegate
public delegate void MyDlegate();
委托对象本身其实并不能被调用 方法名();最终编译后,其实是调用了委托对象的Invoke()方法
调用该方法,就相当于调用了用户传过来的方法
在使用委托变量前,就像使用对象一样,最好判断一下对象是否为null,避免异常
下面来举例子说明一下
用排序的方法来说明这个问题。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _04委托练习排序
{
class Program
{
static void Main(string[] args)
{
Compare cp = new Compare();
//object[] arr = { 1, 25, 24, 12, 23, 65, 42, 10, 88 };
//object[] arr1 = { "素困", "样中考", "勒布朗怎么说", "科比布莱恩特说"};
//声明一个委托
//int[] arr =objs in
object[] objs = {
new Person("张山",21),
new Person("里氏",29),
new Person("无误",11),
new Person("照亮",41),
new Person("前期",31),
};
CompareToDelegate cd2 = new CompareToDelegate(CompareToPerson);
//CompareToDelegate cd=new CompareToDelegate(CompareToInt);
//CompareToDelegate cd1 = new CompareToDelegate(CompareToString);
cp.CompareObject(objs, cd2);
for (int i = 0; i < objs.Length; i++)
{
Console.WriteLine(((Person)objs).Name+"***"+((Person)objs).Age);
}
Console.ReadKey();
}
//定义一个比较int类型的方法
static bool CompareToInt(object n1, object n2)
{
if ((int)n1 > (int)n2)
{
return true;
}
return false;
}
//定一个比较字符串类型的方法
static bool CompareToString(object obj1, object obj2)
{
if (obj1.ToString().Length > obj2.ToString().Length)
{
return true;
}
return false;
}
//定于一个比较person的方法 根据年龄来比较
static bool CompareToPerson(object obj1, object obj2)
{
Person p1 = obj1 as Person;
Person p2 = obj2 as Person;
if (p1.Age > p2.Age)
{
return true;
}
return false;
}
}
public class Compare
{
public void CompareObject(object[] objs, CompareToDelegate cd)
{
for (int i = 0; i < objs.Length - 1; i++)
{
for (int j = 0; j < objs.Length - 1 - i; j++)
{
if (cd(objs[j], objs[j + 1]))
{
object temp = objs[j];
objs[j] = objs[j + 1];
objs[j + 1] = temp;
}
}
}
}
}
public delegate bool CompareToDelegate(object obj1,object obj2);
class Person
{
public Person() { }
string _name = null;
public string Name
{
get { return _name; }
set { _name = value; }
}
int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public Person(string name, int age)
{
this._age = age;
this._name = name;
}
}
}
事件是依靠委托来实现的
委托的不合理:
1.0委托可以直接通过“等号”来赋值,所以可以将前面的注册的处理程序全部覆盖掉,这样做不合适
2.0直接调用委托,触发由于3连接事件只要求只能在点击3次用户控件中的按钮才能被触发
所以在任何地方都恩那个触发该事件是不合理的。
定义一个事件,注意:使用事件来实现,与使用委托
1.0事件是不能在外界触发的,只能在类的内部使用(不能在外面像委托那么直接调用) 就避免了随意被触发的问题
当加了event关键字后,该事件只能在定义事件的类中来触发,绝不能在外部触发,虽然事件定义时使用了关键字public
当你写一个事件的时候,编译器会自动给你3个方法,一个是私有委托,一个公有添加事件的方法,一个公有删除事件的方法
委托和事件的区别:
委托和事件是没有可比性的,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装)委托对象
下面说的是委托的对象(用委托的方式来实现的事件)和(标准的event方式实现)事件的区别,事件的内部是委托实现的。
因为对象事件来讲,外部只能“注册直接+=”,注销自己-=“,外界不可以注销其他的注册这,外界不可以主动触发事件,
因此如果用delegate就没法进行上面的控制,因此诞生了事件这种语法。add remove
事件是用来阉割委托的实例的。事件只能add,remove自己,不能赋值。事件只能+=,-=不能=。
实现事件的步骤
1.0定义委托类型
2.0定义事件变量 你在那个类中使用就定义在那个类中
3.0在条件符合时触发这个事件
4.0注册这个事件
委托的作用:
占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)
在实际调用之前,需要为委托赋值,否则为空。
事件的作用:
事件的作用和委托变量一样,只是在功能上变量有更多的限制。(比如:1.只能通过+=或者
-=来绑定方法(事件处理程序))2.只能在类内部调用(触发事件)
元数据:就是描述自己的信息
类型元数据:描述类型本身的信息