lambda表达式浅显理解,lambda表达式和事件

主意不可能跟变量相同当参数字传送递,如何做,C#概念了信托,就能够把艺术当变量同样传递了,为了轻便,匿超格局传递,省得再声称方法了;再轻巧,lambda表明式传递,比佚名方式越来越直观。

       
委托是寻址方法的.NET版本。在C++中,函数指针只不过是叁个针对内部存储器地址的指针,它不是体系安全的。大家鞭长莫及看清那些指针实际指向什么,像参数和再次回到类型等项就更不能够知晓了。而.NET委托完全两样,委托是连串安全的一个类,它定义了回去值类型和参数的项目。委托类不止包括对章程的引用,也得以分包对五个情势的引用。

GetAStringDemo

public delegate int delegateArithmetic(int a, int b);

       
当要把措施传递给其余措施时,就要求使用委托。

图片 1图片 2

//委托作为参数,方法传递给委托
public int result(int x,int y,delegateArithmetic delAri)
{
return delAri(x, y);
}

       
大家都习于旧贯于把多少作为参数字传送递给艺术,比方上边包车型地铁事例:

using System;

namespace Wrox.ProCSharp.Delegates
{
  class Program
  {
    private delegate string GetAString();

    static void Main()
    {
      int x = 40;
      GetAString firstStringMethod = x.ToString;
      Console.WriteLine("String is {0}", firstStringMethod());

      Currency balance = new Currency(34, 50);

      // firstStringMethod references an instance method
      firstStringMethod = balance.ToString;
      Console.WriteLine("String is {0}", firstStringMethod());

      // firstStringMethod references a static method
      firstStringMethod = new GetAString(Currency.GetCurrencyUnit);
      Console.WriteLine("String is {0}", firstStringMethod());

    }
  }
}

public int Sum(int m,int n)
{
lambda表达式浅显理解,lambda表达式和事件。return m + n;
}

1     int num = int.Parse("666");

View Code

private void button2_Click(object sender, EventArgs e)
{
textBox2.Text = “”;
//委托作为参数,方法传递给委托
var r1 = result(8, 5, Sum);
textBox二.Text = textBox二.Text+”把措施传递给delegate,两数相加结果:” +
r1.ToString()+”\r\n”;

       
所以给艺术传递另2个形式听起来有点意外。而有时有个别方法实施的操作并不是本着数据开始展览的,而是要对另3个艺术开始展览操作。更麻烦的是,在编写翻译时我们不知道第三个格局是什么样,那一个新闻只可以在运营时得到,所以必要将第三个点子作为参数字传送递给第一个主意。

图片 3图片 4

//委托作为参数,匿超形式传递给委托
var r2 = result(8, 5, delegate (int a, int b) { return a – b; });
textBox2.Text = textBox2.Text + “无名情势传递给delegate,两数相减结果:”

       
首先大家要定义一个寄托,定义委托是要小心两点:

namespace Wrox.ProCSharp.Delegates
{
    struct Currency
    {
        public uint Dollars;
        public ushort Cents;

        public Currency(uint dollars, ushort cents)
        {
            this.Dollars = dollars;
            this.Cents = cents;
        }

        public override string ToString()
        {
            return string.Format("${0}.{1,-2:00}", Dollars, Cents);
        }

        public static string GetCurrencyUnit()
        {
            return "Dollar";
        }

        public static explicit operator Currency(float value)
        {
            checked
            {
                uint dollars = (uint)value;
                ushort cents = (ushort)((value - dollars) * 100);
                return new Currency(dollars, cents);
            }
        }

        public static implicit operator float(Currency value)
        {
            return value.Dollars + (value.Cents / 100.0f);
        }

        public static implicit operator Currency(uint value)
        {
            return new Currency(value, 0);
        }

        public static implicit operator uint(Currency value)
        {
            return value.Dollars;
        }
    }

}
  • r2.ToString() + “\r\n”;
  • 经过delegate关键字定义委托(访问修饰符+delegate+再次回到值+委托项目名称+参数列表)

View Code

//委托作为参数,lambda表达式传递给委托
var r3 = result(8, 5, (x, y) => { return x * y; });
textBox二.Text = textBox2.Text +
“lambda表达式传递给delegate,两数相乘结果:” + r三.ToString() + “\r\n”;

SimpleDelegates

//委托作为参数,简易lambda表达式传递给委托
var r4 = result(8, 5, (x, y) => x * y);
textBox二.Text = textBox2.Text +
“简易lambda表明式传递给delegate,两数相乘结果:” + r4.ToString() +
“\r\n”;
}

  • 寄托其实正是指向1个方法,委托的突然不见了参数正是措施的传入参数,委托的重临值正是形式的重回值

    1 public delegate void DTest(string name, int age);

图片 5图片 6

 

  以上代码定义了一个名字为DTest的寄托,并且供给传入方法的再次来到值为void,参数列表为 (string name,
int
age) ,上面大家定义以下六个艺术,并调用委托:

namespace Wrox.ProCSharp.Delegates
{
  class MathOperations
  {
    public static double MultiplyByTwo(double value)
    {
      return value * 2;
    }

    public static double Square(double value)
    {
      return value * value;
    }
  }

}

lambda表明式正是简化了的无名格局,C#编写翻译器编译的时候就把lambda表明式编写翻译成无名氏情势。

 1         public static void Method1(string name)
 2         {
 3             Console.WriteLine(name);
 4         }
 5 
 6         public static bool Method2(string name, int age)
 7         {
 8             Console.WriteLine(name + ":" + age);
 9             return true;
10         }
11 
12         public static void Method3(string name, int age)
13         {
14             Console.WriteLine(name + ":" + age);
15         }
16 
17         public static void Method4(string name, int age)
18         {
19             Console.WriteLine("我是 {0} ,我 {1} 岁!", name, age);
20         }

 1         static void Main(string[] args)
 2         {
 3             //声明委托对象
 4             DTest DG1, DG2;
 5 
 6             //进行对象初始化,并调用委托
 7             //DG1 = new DTest(Method1);//错误:参数列表不一致
 8             //DG1("张三");
 9 
10             //DG1 = new DTest(Method2);//错误:返回值类型不一致
11             //DG1("张三", 20);
12 
13             DG1 = new DTest(Method3);//正确
14             DG1("张三", 20);
15 
16             //便捷的初始化方式,不使用new关键字
17             DG2 = Method3;
18             DG2("张三", 20);
19             DG2 = Method4;//为委托对象重新赋值,将执行新指定的方法
20             DG2("张三", 20);
21 
22             Console.ReadKey();
23         }

View Code

  后边使用的种种委托都只含有二个措施调用。调用委托的次数和调用方法的施行次数同样。借使要反复调用3个格局,将要反复显式调用委托

图片 7图片 8

  可是两个信托也足以涵盖八个章程,那种委托称为多播委托。若是调用多播委托就能够按顺序三番五次调用多方式。此时须要调用方法的返回值为void,不然就不得不猎取委托调用的末梢一个措施的结果。

using System;

namespace Wrox.ProCSharp.Delegates
{
  delegate double DoubleOp(double x);

  class Program
  {
    static void Main()
    {
      DoubleOp[] operations =
      {
        MathOperations.MultiplyByTwo,
        MathOperations.Square
      };

      for (int i = 0; i < operations.Length; i++)
      {
        Console.WriteLine("Using operations[{0}]:", i);
        ProcessAndDisplayNumber(operations[i], 2.0);
        ProcessAndDisplayNumber(operations[i], 7.94);
        ProcessAndDisplayNumber(operations[i], 1.414);
        Console.WriteLine();
      }
    }

    static void ProcessAndDisplayNumber(DoubleOp action, double value)
    {
      double result = action(value);
      Console.WriteLine(
         "Value is {0}, result of operation is {1}", value, result);
    }
  }

}
 1         static void Main(string[] args)
 2         {
 3             DTest DG1, DG2, DG3;
 4             DG1 = Method3;
 5             DG2 = Method4;
 6 
 7             DG3 = DG1 + DG2;
 8             DG3("张三", 20);//将同时执行Method3和Method4
 9 
10             DG3 = DG3 - DG1;
11             DG3("张三", 20);//只执行Method4
12 
13             Console.ReadKey();
14         }

 1         static void Main(string[] args)
 2         {
 3             DTest DG;
 4             DG = Method3;
 5 
 6             DG += Method4;
 7             DG("张三", 40);//同时执行Method3和Method4
 8 
 9             DG -= Method3;
10             DG("张三", 40);//只执行Method4
11 
12             Console.ReadKey();
13         }

View Code

  多播委托实际上是二个派生自System.MulticastDelegate的类,System.MulticastDelegate又派生自基类System.Delegate。System.MulticastDelegate的别的成员同意把七个措施调用链接为多少个列表。

BubbleSorter

  然而采用多播委托会存在三个大难题。当通过多播委托调用多少个点子的时候,假使中间贰个艺术抛出2个十分,那么一切迭代就能够告1段落,也正是说调用方法列表前边的点子将不会被施行。

图片 9图片 10

  比方,大家定义二个法子Method壹和Method2,在Method第11中学抛出八个那些,并透过委托调用那多个点子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Delegates
{
  class Program
  {
    static void Main()
    {
      Employee[] employees =
      {
        new Employee("Bugs Bunny", 20000),
        new Employee("Elmer Fudd", 10000),
        new Employee("Daffy Duck", 25000),
        new Employee("Wile Coyote", 1000000.38m),
        new Employee("Foghorn Leghorn", 23000),
        new Employee("RoadRunner", 50000)
      };

      BubbleSorter.Sort(employees, Employee.CompareSalary);

      foreach (var employee in employees)
      {
        Console.WriteLine(employee);
      }

    }
  }
}
 1     class MyDelegate
 2     {
 3         //定义委托
 4         delegate void DG();
 5         public void Main()
 6         {
 7             DG dg = Method1;
 8             dg += Method2;
 9             dg();
10 
11             Console.ReadKey();
12         }
13 
14         public void Method1()
15         {
16             Console.WriteLine("Method1()执行... ...");
17             throw new Exception("Error!");
18         }
19 
20         public void Method2()
21         {
22             Console.WriteLine("Method()执行... ...");
23         }
24     }

View Code

  结果如图所示:

图片 11图片 12

图片 13   
               图片 14

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Delegates
{
  class Employee
  {
    public Employee(string name, decimal salary)
    {
      this.Name = name;
      this.Salary = salary;
    }

    public string Name { get; private set; }
    public decimal Salary { get; private set; }

    public override string ToString()
    {
      return string.Format("{0}, {1:C}", Name, Salary);
    }

    public static bool CompareSalary(Employee e1, Employee e2)
    {
      return e1.Salary < e2.Salary;
    }
  }

}

  我们能够看看Method二()并不曾被实行。为了防止那种气象,大家应协调迭代艺术列表。Delegate类定义了GetInvocationList()方法,它回到叁个Delegate对象数组。大家能够使用这些委托调用与寄托有关的不二诀要,捕获至极,并继续下一遍迭代。

View Code

 1         public void Main()
 2         {
 3             DG dg = Method1;
 4             dg += Method2;
 5             Delegate[] methodList = dg.GetInvocationList();
 6             foreach (DG d in methodList)
 7             {
 8                 try
 9                 {
10                     d();
11                 }
12                 catch (Exception e)
13                 {
14                     Console.WriteLine(e.Message);
15                 }
16             }
17         }

图片 15图片 16

图片 17

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Delegates
{
  class BubbleSorter
  {
    static public 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);


    }
  }

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图