委托

作者: ottox | 来源:发表于2018-11-13 21:26 被阅读1次

委托的概念:

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。事件是一种特殊的委托。
本质是持有一个或多个方法的对象;委托和典型的对象不同,执行委托实际上是执行它所“持有”的方法。如果从C++的角度来理解委托,可以将其理解为一个类型安全的、面向对象的函数指针。


image.png

如何使用委托

①声明委托类型(delegate关键字)

②使用该委托类型声明一个委托变量

③为委托类型增加方法

④调用委托执行方法


image.png

声明委托

delegate <函数返回类型> <委托名> (<函数参数>)

image.png

a、委托类型的声明看上去与方法的声明很类似,有返回类型和签名。返回类型和签名指定了委托接受的方法的形式
b、委托类型与方法声明的不同之处:
▲ 委托是以关键字delegate开头的
▲ 委托没有方法主体

例子:public delegate void MyDelegate(int number);//定义了一个委托MyDelegate,它可以注册返回void类型且有一个int作为参数的函数

委托的实例化

  • 使用new关键字

委托实例化的原型是
<委托类型> <实例化名>=new <委托类型>(<注册函数>)
例子:MyDelegate _MyDelegate=new MyDelegate(CheckMod);//用函数CheckMod实例化上面的MyDelegate 委托为_MyDelegate
简写:MyDelegate _MyDelegate=CheckMod;

  • 使用匿名方法

<委托类型> <实例化名>=delegate(<函数参数>){函数体};

  • 使用Lambda表达式
class Program
    {
        //声明委托
        delegate int MyDelegate(int x, int y);

        static void Main(string[] args)
        {
            //实例化委托
            //1、使用new关键字
            MyDelegate _myDelegate = new MyDelegate(GetSum);
            //  MyDelegate _myDelegate = GetSum;

            //2、使用匿名方法
            MyDelegate myDelegate = delegate(int x, int y)
            {
                return x + y;
            };

            //3、使用Lambda表达式
            MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
        }

        static int GetSum(int x, int y)
        {
            return x + y;
        }
    }

泛型委托

泛型委托原型:
delegate <T1> <委托名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)
例如:delegate T2 DelegateDemo<T1,T2>(T1 t);//定义有两个泛型(T1,T2)的委托,T2作为委托函数返回类型,T1作为委托函数参数类型

static boo Check(int i)
{
     if(i%2==0)

     {

          return true; 

    }

     return false;
}

static void Main(string[] args)
{
      DelegateDemo<int, bool> _delegate =Check;//将泛型委托委托<T1,T2>实例化为<int,bool>,即表示有一个int类型参数且返回类型是bool的函数.
      Console.WriteLine(_delegate(9));//false
}

C#内置泛型委托

namespace DelegateDemo
{
    class Program
    {
        //声明委托
        delegate int MyDelegate(int x, int y);

        static void Main(string[] args)
        {
            //1、Action<T>只能委托必须是无返回值的方法
            Action<string> _action = new Action<string>(SayHello);
            _action("Hello World");

            //2、Fun<TResult>只是委托必须有返回值的方法
            Func<int, bool> _func = new Func<int, bool>(Check);
            _func(5);

            //3、Predicate:此委托返回一个bool值,该委托通常引用一个"判断条件函数"。
            //需要指出的是,判断条件一般为“外部的硬性条件”,比如“大于50”,而不是由数据自身指定,如“查找数组中最大的元素就不适合”。
            Predicate<int> _predicate = new Predicate<int>(Check);
            //使用Lambda表达式
            Predicate<int> predicate = p => p % 2 == 0;
            _predicate(26);
        }

        static void SayHello(string strMsg)
        {
            Console.WriteLine(strMsg);
        }

        //返回值为bool值
        static bool Check(int i)
        {
            if (i % 2 == 0)
            {
                return true;
            }
            return false;
        }       
    }
}

多播委托

实例化委托时必须将一个匹配函数注册到委托上来实例化一个委托对象,但是一个实例化委托不仅可以注册一个函数还可以注册多个函数,注册多个函数后,在执行委托的时候会根据注册函数的注册先后顺序依次执行每一个注册函数。

函数注册委托的原型:
<委托类型> <实例化名>+=new <委托类型>(<注册函数>)
例如:MyDelegate _myDelegate+=new MyDelegate(CheckMod);//将函数CheckMod注册到委托实例_checkDelegate上
在.net 2.0开始可以直接将匹配的函数注册到实例化委托:
<委托类型> <实例化名>+=<注册函数>
例如:MyDelegate _myDelegate+=CheckMod;//将函数CheckMod注册到委托实例_myDelegate上

注意:委托必须先实例化以后,才能使用+=注册其他方法。如果对注册了函数的委托实例从新使用=号赋值,相当于是重新实例化了委托,之前在上面注册的函数和委托实例之间也不再产生任何关系。

有+=注册函数到委托,也有-=解除注册

例如:MyDelegate _myDelegate-=CheckMod;

如果在委托注册了多个函数后,如果委托有返回值,那么调用委托时,返回的将是最后一个注册函数的返回值。

namespace DelegateDemo
{
  class Program
  {
      //声明委托
      delegate int MyDelegate(int x, int y);

      static void Main(string[] args)
      {
          MyDelegate _myDelegate = new MyDelegate(fun1);
          _myDelegate += fun2;
          Console.WriteLine(_myDelegate(10,23));

          Console.ReadKey();//输出10,返回最后一个注册函数的返回值
      }

      static int fun1(int x, int y)
      {
          return x + y;
      }

      static int fun2(int x, int y)
      {
          return x;
      }      
  }
}

委托实例

①简单带参数委托DEMO

delegate void MyDel(int value); //声明委托类型

    class Program
    {
        void PrintLow(int value)
        {
            Console.WriteLine("{0} - LowValue", value);
        }

        void PrintHigh(int value)
        {
            Console.WriteLine("{0} - HighValue", value);
        }

        static void Main(string[] args)
        {
            Program program = new Program();

            MyDel myDel; //声明委托类型

            //获取0~99之间的一个随机数
            Random random = new Random();
            int randomValue = random.Next(99);

            //创建一个包含具体方法的委托对象并将其赋值给myDel变量
            myDel = randomValue < 50 ?
                new MyDel(program.PrintLow) : new MyDel(program.PrintHigh);

            //执行委托
            myDel(randomValue);

            Console.ReadKey();
        }
    }

②简单无参数多方法列表委托DEMO

delegate void PrintFunction();

class Test
{
   public void Print1()
   {
      Console.WriteLine( "Print1 -- instance" );
   }

   public static void Print2()
   {
      Console.WriteLine( "Print2 -- static" );
   }
}

class Program
{
   static void Main()
   {
      Test t = new Test();                 
      PrintFunction pf;                        
      pf = t.Print1; 

      pf += Test.Print2;
      pf += t.Print1;
      pf += Test.Print2;

      if ( pf != null )                         
      {
          pf();    
       }                          
      else
       {  
           Console.WriteLine( "Delegate is empty" ); 
       }
   }
}

③带返回值的委托DEMO

delegate int MyDel(); 

class MyClass
{
   int IntValue = 5;

   public int Add2()
   {
      IntValue += 2; 
      return IntValue;
   }

   public int Add3()
   {
      IntValue += 3; 
      return IntValue;
   }
}

class Program
{
   static void Main()
   {
      MyClass mc = new MyClass();

      MyDel mDel = mc.Add2;      
      mDel += mc.Add3;          
      mDel += mc.Add2;          

      Console.WriteLine( "Value: {0}", mDel() );
   }
}

相关文章

  • 第8章:委托、Lambda表达式和事件

    #1. 委托1.1 声明委托1.2 使用委托1.3 简单委托示例1.4 Action和Func委托1....

  • Delegates, events, lambda expres

    Delegates 委托 委托是一个对象,它知道如何调用一个方法 委托类型和委托实例 委托类型定义了委托实例可以调...

  • 哪些事项是不能办理委托公证的?

    很多种委托事项都可以办理公证,比如委托领取公积金、委托诉讼、委托招投标、委托处理工商理赔、房产委托...等,所...

  • 哪些委托是不能公证的?

    很多种委托事项都可以办理公证,比如委托领取公积金、委托诉讼、委托招投标、委托处理工商理赔、房产委托...等,所...

  • JEX合约交易--委托保证金

    用户进行交易委托将可能会需要冻结委托保证金,其具有如下几项规则: 买入委托所需的委托保证金 = 委托价格 * 委托...

  • Kotlin-委托,是否被低估了?

    1、属性委托 kotlin中的委托主要分为类的委托和属性的委托,我们先重点来看属性委托,用的比较多。 标准委托 k...

  • 隐藏之冰山委托

    冰山委托(Iceberg Order)。冰山委托是隐藏部分委托数量(不在系统中公开显示)的委托,也称为隐藏委托(h...

  • 17_DoTween

    委托,Lambda, LinQ串讲 什么是委托 委托类型是怎么声明出来的 泛型委托 我们必须自己创建委托类型吗? ...

  • Kotlin中的委托

    Kotlin中的委托 啥是委托 其实kotlin中的委托的理念就是委托模式也是叫做代理模式;在Kotlin中委托有...

  • Kotlin学习之类与对象3

    委托 由委托实现 委托模式(https://zh.wikipedia.org/wiki/委托模式)已经证明是实现继...

网友评论

      本文标题:委托

      本文链接:https://www.haomeiwen.com/subject/rfqrfqtx.html