欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# 委托 事件

程序员文章站 2022-03-24 11:41:49
一:什么叫委托 通过反射发现,委托其实是一个类,继承自System.MulticastDelegate,但是System.MulticastDelegate这个类是特殊类,不能被继承 二:委托的声明 委托可以声明在类外面,可以声明再类里面 三:委托的实例和调用 private int GetSome ......

一:什么叫委托

通过反射发现,委托其实是一个类,继承自system.multicastdelegate,但是system.multicastdelegate这个类是特殊类,不能被继承

 

二:委托的声明 

 public delegate void noreturnnoparaoutclass();
 public class mydelete
 {
      public delegate void noreturnnopara<t>(t t);
      public delegate void noreturnnopara();
      public delegate void noreturnwithpara(int x, int y);
      public delegate int withreturnnopara();
      public delegate string withreturnwithpara(out int x, ref int y);
    }

委托可以声明在类外面,可以声明再类里面

 

三:委托的实例和调用 

C#  委托 事件
      private int getsomething()
        {
            return 1;
        }
        private int getsomething2()
        {
            return 2;
        }

        private int getsomething3()
        {
            return 3;
        }
        private void donothing()
        {
            console.writeline("this is donothing");
        }
        private static void donothingstatic()
        {
            console.writeline("this is donothingstatic");
        }
        public string parareturn(out int x, ref int y)
        {
            throw new exception();
        }
view code

 

//多种途径实例化,要求传递一个参数类型,返回值都跟委托一致的方法
{
   withreturnwithpara method = new withreturnwithpara(parareturn);
   int x = 0;
   int y = 0;
   var dd = method.invoke(out x, ref y);
 }
//begininvoke
{
   withreturnnopara method = new withreturnnopara(this.getsomething);
   int iresult = method.invoke();
   iresult = method();
   var result = method.begininvoke(null, null);//异步调用
   method.endinvoke(result);
}
{
   noreturnnopara method = new noreturnnopara(this.donothing);
   //委托实力的调用,参数和委托约束的一致
    method.invoke(); //1
    //method(); //2
    //method.begininvoke(null, null); //3
    //this.donothing(); //1,2,3都等同于this.donothing

}
{
     noreturnnopara method = new noreturnnopara(donothingstatic);
}
{
    noreturnnopara method = new noreturnnopara(student.studyadvanced);
}
{
    noreturnnopara method = new noreturnnopara(new student().study);
}

 

四:为什么要使用委托

有时候我们声明一个方法,直接调用蛮好的,为啥还要使用委托,然后还要先声明,再实例化,再inovke调用呢?

下面我们举个例子,比如一个人问好这件事情,不同人问候方式不一样,我们会先定义一个类型,如枚举

public enum peopletype
 {
        chinese,
        america,
        japanese
 }

然后通过不同的类型来判断问候方式不同,如下

        /// 为不同的人,进行不同的问候
        /// 传递变量--判断一下----执行对应的逻辑
        /// </summary>
        /// <param name="name"></param>
        /// <param name="peopletype"></param>
        public void sayhi(string name, peopletype peopletype)
        {
            switch (peopletype)
            {
                case peopletype.chinese:
                    console.writeline($"{name}晚上好");
                    break;
                case peopletype.america:
                    console.writeline($"{name},good evening");
                    break;
                case peopletype.japanese:
                    console.writeline($"{name},&&%*^^***@@@&&&&");
                    break;
                default:
                    throw new exception("wrong peopletype"); //遇到异常报错
            }
        }

这样做的好处是:以后如果增加公共逻辑等比较容易,但是如果类型比较多,这个方法会变成无限制改动,导致方法难以维护,于是很多人想着增加分支,就增加方法--不影响别的方法的思路来改善

  public void sayhichinese(string name)
  {
         console.writeline($"{name}晚上好");
  }
  public void sayhijapanese(string name)
  {
         console.writeline($"{name},&&%*^^***@@@&&&&");
  }
  public void sayhiamerican(string name)
  {
          console.writeline($"{name},good evening");
  }

然后上层判断调用

这样做的好处是:修改某个方法--不影响别的方法 ,但是缺点却是:增加公共逻辑---多个方法就有很多重复代码

那么我们想:既增加逻辑方便,又维护简单,鱼肉熊掌,如何兼得呢?

我们可以把相应的逻辑做为参数传进来,这样就解决了我们的问题

具体我们可以按照以下来做:

  public void sayhiperfact(string name, sayhideletegate method)
  {
      console.writeline("增加开始日志");
      method.invoke(name);
      console.writeline("增加结束日志");          
  }
  public delegate void sayhideletegate(string name);

然后调用的时候如下:

  sayhideletegate method = new sayhideletegate(sayhichinese);

这样就做到了

1:逻辑解耦,方便维护 

2:代码重构,去掉重复

其实这也是我们选择使用委托的两大优点

注意:以上我们纯粹为了定义委托而定义委托,其实框架已经我们帮我们定义了action 和func这两个委托,action是没有返回值,func是有返回值的,这两个委托类已经足够我们使用了,所以有时候我们使用的时候,没有必要自己再去定义,而直接使用即可