温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#委托与事件

发布时间:2020-07-06 17:14:12 来源:网络 阅读:1107 作者:dongdong200514 栏目:编程语言

C#中的委托可以实现将方法本身作为参数传递,也就是说,委托是方法的引用,我们一旦为委托分配了方法,那这个委托就和这个方法具有完全相同的行为。委托对象的引用中包含一个指向这个方法的指针。通过委托把方法的引用封装到对象中,然后将委托对象传递给调用引用方法的代码。

与委托类型匹配的方法必须满足的条件:

两者具有相同的参数树木你,并且类型相同、顺序相同、参数的修饰符也相同。两者具有相同的返回类型。

定义实例方法Add,将该方法作为自定义类型FirstDelegate的匹配方法。在Program类中定义一个委托类型FirstDelegate,接着在Main中创建该委托类型实例fd,并绑定到Add方法。

public class Test
{
    public int Add(int a, int b){
        return a+b;
    }
}
public delegate int FirstDelegate(int a, int b);//定义一个委托类型
Main(){
    Test t = new Test();
    FirstDelegate fd = t;//创建委托类型fd并绑定到Add方法
    int sum = fd(1,2);
}


匿名方法:简化委托引用方法的过程

//定义一个委托类型
delegate void Dele(int x);
//用匿名方法创建委托
Dele de = delegate(int x){
    //委托所调用的代码。。。
}


委托的发布和订阅(按书的说法如下):

首先要通过发布者来发布这个委托,然后定义一个事件触发器,在这个触发器被激发后,会调用这个委托,然后委托根据自身的订阅情况,再进行回调委托(事件)的处理方法,因为委托事件已经通过"+="符号链接到该处理方法上。

还是按例子进行说明~~

//定义一个委托类型Ring,参数传入1表示上课,2表示下课
public delegate void Ring(int kind);
/*定义委托发布者类型SchoolRing,并定义Ring类型的公有成员,再定义一个成员方法Active,用来实现激发委托操作*/
public class SchoolRing{
    pulbic Ring OnBell;//委托发布
    public void Active(int kind){
        if(kind==1||kind==2){
//不为空说明已经订阅。回调OnBell委托所订阅的具体方法
            if(OnBell!=null) OnBell(kind);
        }else{}
    }
}

//定义订阅者类

public class Students{//定义订阅者类
    public void Subscribe(SchoolRing sr){//学者订阅铃声这个委托事件
        sr.OnBell += SchoolActive;//通过委托的链接操作进行订阅
    }
    public void SchoolActive(int kind){
        if(kind==1){}
        else if(kind==2){}
    }
    public void Cancel(SchoolRing sr){//取消订阅铃声动作
        sr.OnBell -= SchoolActive;
    }
}

//当发布者SchoolRing类的对象调用其Active方法进行打铃时,就会自动调用Students对象的SchoolActive这个事件处理方法

SchoolRing sr = new SchoolRing();//创建事件发布者实例
Students st = new Students();//创建事件订阅者实例
st.Subscribe(sr);//学生订阅学校铃声
sr.Activte(Convert.ToInt32(Console.ReadLine()));//开始打铃


.NET类库中定义一个EventHandler类,并且尽量使用这类作为事件的委托类型,该委托类型的定义:

public delegate void EventHandler(object sender,EventArgs e);

其中object类型的参数sender表示引发事件的对象,由于事件成员只能由类型本身出发,所以通常传为this。

上面代码可修改为:

/*EventHandler委托的第二个参数e表示事件中包含的数据。如果发布者还要向订阅者传递额外的事件数据,需要定义EventArgs的派生类*/
public class RingArgs: EventArgs{
    private int kind;   
    public int Kind{get{return kind;}}
    public RingArgs(int kind){this.kind = kind;}
}
//Students类对OnBell事件的处理方法修改
public void SchoolActive(object sender, EventArgs e){
    if(((RingArgs)e).Kind == 1){}
    else if(((RingArgs)e).Kind == 2){}
}

//SchoolRing的实例在出发OnBell事件时,可以将该类型(RingArgs)的对象作为参数传递给EventHandler委托

public event EventHandler OnBell;//委托发布
public void Active(int kind){
    if(kind == 1 || kind ==2){
        if(OnBell!=null)
            OnBell(this, new RingArgs(kind));//回调委托所订阅的方法
    }
}
public void SchoolActive(object sender, EventArgs e){
    if(((RingArgs)e).Kind == 2){}
    else if(...)
}


//在之前讲到的Windows控件中其实也涉及到事件的内容,我们通常在Form1.cs中定义事件,在Form.Designer.cs中关联事件

private void button1_Click(object sender , EventArgs e){}
button1.Click += new EventHandler(button1_Click);//关联事件


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI