c#基础知识---委托,匿名函数,lambda

编辑: admin 分类: c#语言 发布时间: 2022-01-18 来源:互联网
目录
  • 前言:
  • 1.委托的声明
    • 1.1.delegate
      • 1.1.1. 0-23个参数,可以有返回值也可以没有返回值
      • 1.1.2.委托的调用
      • 1.1.3.委托的多播
    • 1.2.Action
      • 1.3.Func
        • 1.4.predicate
        • 2.委托的实例化
          • 2.1.delegate
            • 2.2.Action的使用
              • 2.3.Func的使用
                • 2.4 委托实现冒泡排序
                • 3.匿名函数与lambda
                  • 3.1什么是匿名函数
                    • 3.2.lambda
                    • 4.综上:

                      前言:

                             C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。委托(Delegate)特别用于实现事件和回调方法。所有的委托都派生自 System.Delegate 类。把一个方法当作参数传递,让其它方法进行调用执行。

                      1.委托的声明

                      委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同标签的方法。

                      1.1.delegate

                      1.1.1. 0-23个参数,可以有返回值也可以没有返回值

                      public delegate int MyDelegateEventHandler (string parm);

                      注:(1).此委托指向的方法必须是参数为string类型,返回类型为int类型的。其他声明类比所得。

                        (2).EventHandler是c# 命名规范,当然我理解规范就是可以随意啦。

                             (3).委托调用时必须判断是否为null不然会报异常

                             (4).事件也是一种委托

                      1.1.2.委托的调用

                      MyDelegateEventHandler fun=new MyDelegateEventHandler(method);
                      or
                      MyDelegateEventHandler fun=method;
                      // fun不为空,则调用回调方法
                       if (fun!= null)
                       {
                       fun(val);
                       }
                       //fun?.Invoke(val); 简化版本调用

                      1.1.3.委托的多播

                      每个委托都只包含一个方法调用,如果调用多个方法,就需要多次显示调用这个委托。如果同一个委托调用多个方法,我们就可以用多播委托

                      public delegate void MyDelegate ();
                      
                      public voidMyMethod()
                      {
                       //#
                      }
                      public void MyMethod1()
                      {
                       //#
                      }
                      public void MyMethod2()
                      {
                       //#
                      }
                      MyDelegateEnventHander myDelegate;
                      myDelegate=new MyDelegateEventHander(MyMethod);
                      myDelegate+=new MyDelegateEventHander(MyMethod1);
                      ...........
                      //调用
                      myDelegate();

                       注:

                        1.委托对象可使用 "+" 运算符进行合并;

                        2."-" 运算符可用于从合并的委托中移除组件委托;

                        3.委托指定方法类型必须一致;

                        4.返回类型一般为void,但非必须;

                        5.GetInvocationList获取委托索引

                      if (MyDelegate != null) 
                       System.Delegate[] dels = MyDelegate .GetInvocationList(); 
                      for (int i = 0; i < dels.Length; i++) 
                        {
                       MyDelegate -= dels[i] as MethodDelegate;
                         }

                      以上是利用GetInvocationList获取委托索引的一个简单应用。

                      1.2.Action

                      Action至少0个参数,至多16个参数,无返回值。

                      Action 表示无参,无返回值的委托
                      Action<int,string> 表示有传入参数int,string无返回值的委托
                      Action<int,string,bool> 表示有传入参数int,string,bool无返回值的委托
                      Action<int,int,int,int> 表示有传入4个int型参数,无返回值的委托
                       public void Test<T>(Action<T> action,T p)
                       {
                       action(p);
                       }

                      1.3.Func

                      Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void

                      Func是无返回值的泛型委托
                      Func<int> 表示无参,返回值为int的委托
                      Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
                      Func<object,string,int> 表示传入参数为object, string 返回值为int的委托
                      Func<T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型)返回值为int的委托

                      1.4.predicate

                      1.predicate 是返回bool型的泛型【本文由http://www.nextecloud.cn/hk.html首发,转载请保留出处,谢谢】委托;

                      2.predicate<int> 表示传入参数为int 返回bool的委托;

                      3.Predicate有且只有一个参数,返回值固定为bool;

                      public delegate bool Predicate<T> (T obj)

                      2.委托的实例化

                      2.1.delegate

                      public delegate int MyDelegateEventHandler (string parm)
                      public int MyMethod(string parm)
                      {
                       //#
                      }
                      MyDelegateEventHandler MyDelegate=new MyDelegateEventHandler(MyMethod)

                      注:委托实例化的时候,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。委托参数中的方法不含参数。

                      2.2.Action的使用

                      public void Test<T>(Action<T> action, T p)
                       {
                       action(p);
                       }
                       private void Action(string s)
                       {
                       #
                       }
                      //调用
                      Test<string>(Action,"wyl");

                      2.3.Func的使用

                      public int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b)
                      {
                       return func(a, b);
                      }
                      private int Fun(int a, int b)
                      {
                       #
                      }
                      //调用
                      Test<int,int>(Fun,100,200)

                      2.4 委托实现冒泡排序

                      //定义对象
                      class Student
                       {
                       public string Name { get; private set; }
                       public decimal Scores{ get; private set; }
                      
                       public Student(string name, decimal scores)
                       {
                       this.Name = name; this.Scores= scores;
                       }
                       public override string ToString()
                       {
                       return string.Format("{0},{1:C}",Name,Scores);
                       }
                       public static bool CompareScores(Student e1,Student e2)
                       {
                       return e1.Scores< e2.Scores;
                       }
                       }
                      //利用委托实现冒泡
                      class BubbleScores
                       {
                       public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison)
                       {
                       bool swapped = true;
                       do
                       {
                       swapped = false;
                       for (int i = 0; i < sortArray.Count - 1; i++)
                       {
                        if (comparison(sortArray[i + 1], sortArray[i]))
                        {
                        T temp = sortArray[i];
                        sortArray[i] = sortArray[i + 1];
                        sortArray[i + 1] = temp;
                        swapped = true;
                        }
                       }
                       } while (swapped);
                       }
                       }
                      //调用
                      Student[] students={new Student("wyl", 100),#};
                      BubbleSorter.Sort(students, Student.CompareScores);
                      foreach(var student in students)
                       Console.WriteLine(student);

                      3.匿名函数与lambda

                      3.1什么是匿名函数

                      匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用。

                      可以使用匿名函数来初始化命名委托(无需取名字的委托),或传递命名委托(而不是命名委托类型,传递一个方法块,而不是委托类型)[callback的方式]作为方法参数。

                      MyDelegate funDelegate = delegate(string s) { Console.WriteLine(s); };
                      funDelegate ("this is anonymous delegate");

                      3.2.lambda

                      lambda表达式实际上是一个匿名函数。编译器在看到lambda之后会在类中自动定义一个新的私有方法。lambda必须匹配委托!其中lambda是从c#3.0后引用的

                      lambda的语法:

                      参数 => 方法体。

                      =>左边是要传入的参数,本例中是传入一个Int类型的变量,=>右边是具体的代码。

                      //如果不传递参数:
                      ()=>Console.WriteLine("Hello World!")
                      //传递一个参数:
                      (int n)=>Console.WriteLine(n.ToString()) 
                      //或者去掉()和int 编译器会自己推断类型:
                      n=>Console.WriteLine(n.ToString())
                      //传递多个参数:
                      (int n ,int m)=>Console.WriteLine(n+m) 
                      //或者编译器自己推断类型:
                      (n , m)=>Console.WriteLine(m+n)

                      4.综上:

                      1.委托类似于 C++ 函数指针。

                      2.委托允许将方法作为参数进行传递。

                      3.委托可用于定义回调方法。

                      4.委托可以链接在一起;多播。

                      5.方法不必与委托签名完全匹配。

                      以上就是c#基础知识---委托,匿名函数,lambda的详细内容,更多关于c# 委托,匿名函数,lambda的资料请关注海外IDC网其它相关文章!

                      【本文转自:黄冈网站推广 转载请说明出处】