c# 委托小结

  委托在c# 1 时代产生出来的。其对C#的发展产生了深远的影响。委托是将一个特定的方法绑定到一个特定的对象上。

  委托类型直接派生雨System.MulticastDelgate类型。委托类型成员中最为重要的是Invoke方法,Invoke 方法决定了委托类型可以如何使用。同时绑定到委托的方法的签名都必须与Invoke的方法签名一致。

    例如:delegate void Add(int a,int b)  类型的Invoke方法签名会类似 virturl void Invoke(int ,int);

      委托对象维护两个字段:1.方法指针;2.目标对象的引用。委托执行会直接使用目标对象的引用地址JMP到方法的地址执行方法。

 

c#1 要创建委托实例。必须指定委托的类型和操作。

  •  声明委托  public delegate bool CompareHandler(int x,int y);
  • 操作方法:
    public bool CompareData(int x,int y)
    {
       return x>y;
    }

     

  • 绑定  CompareHandler handler = new CompareHandler(CompareData);
  • 构建链式委托采用  Delegate.Combine(handler,...) , Delegate.Remove();

c# 2.0 时代加入了语法糖 += ,-=构建链式委托.同时支持委托的协变与逆变。

 

方法组转换:

      方法组就是重载方法。方法组可以隐式转换为兼容的委托。

  public delegate void EventHandler(object o,EventArgs e);

       public TestMethod(){}

      public TestMethod(object o,EventArgs e){}

     EventHandler h=TestMethod;

不过 方法组不能隐式的转换Delegate,  显示转换如下 

Delegate  d = (EventHandler)TestMethod

并且对于已经重载转换委托类型的方法,就不能把它作为方法参数使用,下面的 就会出现错 参数 1: 无法从“方法组”转换为“System.Delegate” 

 public delegate void EventHandler(object o, EventArgs e);
        public static void TestMehod(object o, EventArgs e)
        {
        }

        public static void TestMethodt(Delegate d)
        {
        }

            TestMethodt(TestMehod);

需要采用强制转型  TestMethodt((EventHandler)TestMehod);

 

委托匿名方法转换

    匿名方法转换 在ECMA 344 13.5

         1.无返回类型参数匹配 

            Action<int> s = delegate{ };
            Action<int> a = delegate(int x) { };

 

        2.匿名方法闭包: 

      闭包 抓取的是就是变量本身。如下的两种情况。对于counter来说List中抓的都是新的实例。对于i所有的list都是同一个变量

List<Action> lst = new List<Action>(); 

for (int i=0;i<3;++i) { 
int counter = i*10;
 lst.Add(delegate { Console.WriteLine("values is "+i); i++; }); } 

foreach (var t in lst) { t(); }
 lst[0](); lst[0](); lst[2](); lst[2]();
List<Action> lst = new List<Action>();
            for (int i=0;i<3;++i)
            {
                int counter = i*10;
                lst.Add(delegate
                {
                    Console.WriteLine("values is " + counter);
                    counter++;
                });}
            foreach (var  t in lst){
                t();
            }
            lst[0]();lst[0]();lst[2]();lst[2]();

匿名方法到lamda表达式:

    public static void GetString()
        {
             ExtString(i =>
            {
                i += "Hel World!"; 
                
                Console.Write(i);
            });
        }

        public static void ExtString(Action<string> i)
        {
            const string mol = "I Love ";
            i.Invoke(mol);
        }

    lamda表达式本身就是匿名函数。匿名函数的要求也适用于它。捕获变量的生命周期也与匿名方法一样。



转载于:https://www.cnblogs.com/nessie/p/3860333.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值