c#专题——委托和Lambda表达式

为什么要使用委托呢?委托是将方法作为参数进行传递,简化了代码

一、委托的声明和实例化

 public class TestDelegate
    {
        public delegate int GetValueDelegate(int x, int y);//声明一个委托类型
        public int GetValue(GetValueDelegate getValueDelegate, int x, int y)//将委托类型的实例当作方法的形参
        {
            return getValueDelegate(x, y);//调用委托
        }


    }
 public partial class Form1 : Form
    {
     

        TestDelegate.GetValueDelegate getValueDelegate;//定义一个委托类型的引用


        private int GetMax(int x, int y)
        {
            return x > y ? x : y;
        }
        private int GetMin(int x, int y)
        {
            return x < y ? x : y;
        }


        public Form1()
        {
            InitializeComponent();
            getValueDelegate = GetMax;//使用方法直接实例化委托,获取最大值
           //getValueDelegate =new    TestDelegate.GetValueDelegate( GetMax);//也可以这样实例化委托
            TestDelegate testDelegate = new TestDelegate();
            int value = testDelegate.GetValue(getValueDelegate, 100, 200);
           }

       }

二、Lambda表达式
1)语句Lambda
在上面的程序中我们看到,如果要实例化一个委托,则需要定义一个方法,语句Lambda的作用就是就是我们使用一个特殊的形式去描述一个方法,而不是直接定义一个全新的方法,如下:
旧的使用形式:
int value = testDelegate.GetValue(getValueDelegate, 100, 200);
1、 新的使用形式:
int value = testDelegate.GetValue((int x,int y)=> { return x > y ? x : y; }, 100, 200);
2、如果可以推断类型的话,还可以将参数列表中的x,y的类型省略,如下:
int value = testDelegate.GetValue(( x, y)=> { return x > y ? x : y; }, 100, 200);

3、如果遇到只有一个参数的情况

   public class TestDelegate
    {
        
        public void GetValue(Action<int> getValueDelegate, int x)
        {
             getValueDelegate(x);
        }
    }

public Form1()
{
InitializeComponent();

        TestDelegate testDelegate = new TestDelegate();

        testDelegate.GetValue( x=> { Console.WriteLine(x); },100);//可以直接将形参列表的圆括号去除了
        }

4、如果没有参数,则如下:

 public class TestDelegate
    {
        
        public void GetValue(Action getValueDelegate)
        {
             getValueDelegate();
        }

    }
 public Form1()
        {
            InitializeComponent();
            

            TestDelegate testDelegate = new TestDelegate();

            testDelegate.GetValue( ()=> { Console.WriteLine("我没有参数"); });//直接用了一个空的圆的括号
            }

2)表达式Lambda
表达式Lambda将语句Lambda中的大括号以及return语句都直接省略了,如下:

public class TestDelegate
    {
        
        public int GetValue(Func <int,int> getValueDelegate,int x)
        {
           return  getValueDelegate(x);
        }

    }

public Form1()
{
InitializeComponent();

        TestDelegate testDelegate = new TestDelegate();

        testDelegate.GetValue( x=> x+1 ,100);//return关键字,大括号都没了
        }

三、Action和Func
如果我们总是自定义委托就比较麻烦,所以c#为我们提供了Action和Func这两个委托类型,注意以下三点:
1)Action是没有返回值的委托类型;
2)Func是有返回值的委托类型;
3)可以声明Action或者Func的委托类型数组;
4)委托没有结构相等性,即不能将委托类型的对象引用转换成不相关的委托类型,唯一的办法是通过Invoke方法去调用旧委托的方法
Action action1 = () => Console.WriteLine(“我是无参委托1”);
Action action2 = () => Console.WriteLine(“我是无参委托2”);
action2 = action1.Invoke;
action2();
5)委托的逆变性
Action action3 = ( str) => Console.WriteLine(str);
Action action4 = (obj) => Console.WriteLine(obj);
action3 = action4;//逆变

6)委托的协变性
Func func1=()=> “1”;
Func func2=()=> 100;
func2 = func1;//协变
四、外部变量

c#5.0之前输出是3,3,3,C#5.0输出1,2,3,参考c#本质论,但是自己实验发现好像都是1,2,3

var items = new string[] { "1", "2", "3" };
            var actions = new List<Action>();
            foreach (string item in items )
            {
                actions.Add(()=> { Console.WriteLine(item); });
            }

            foreach (Action action in actions )
            {
                action();
            }

对于上述代码,item就是一个外部变量

五、表达式树

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c#上位机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值