【C#】委托复习

委托是持有一个或多个方法的对象。但委托与典型的对象不同,可以执行委托,这时委托会执行它所“持有”的方法

1.定义委托

delegate关键字 + 返回值的数据类型 +委托名
例:delegate string GetStr();//这一步就是声明委托类型
定义返回值为string的委托,委托名为GetStr
创建实例

int x=40;
//GetStr a=new GetStr(x.toString);//让a指向整形x中的toString方法
GetStr a=x.toString;//直接通过等号将方法赋值给委托对象
Console.WriteLine(a());//调用a()方法 实际就是引用了toString()方法
private delegate void PrintMed();
static void PrintStr(PrintMed med){ //函数中参数可以使用委托变量
    med();//调用委托变量对应的方法(函数)
}

void Method1(){
    Console.WriteLine("Method1");
}
void Method2(){
    Console.WriteLine("Method2");
}
static void Main(String[] args){
    PrintMed a=Method1;
    PrintStr(a);//调用委托变量a中对应的方法Method1
    a=Method2;//改变委托变量a的方法为Method2
    PrintStr(a);//调用Method2方法
}

Action委托 一定无返回值 但可以传入参数Action
T为传入的数据类型

Func委托 必须有返回值 Func T代表返回的数据类型
也可以传入参数例如
Func<string,int> 最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须跟指向的方法的参数类型按照顺序对应

2.给委托赋值

由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变中的引用。旧的委托对象会被垃圾回收站回收

例:

void Test1(){}
void Test2(){}
...
Mydel delVar;//声明一个委托对象
delVar=Test1;
delVar=Test2;//此时执行delVar()只有Test2方法

3.给委托添加方法

上面我们知道委托是不变的,不过C#提供了看上去可以为委托添加方法的语法,即使用+=运算符

例:

class Program
    {
        static void Test1()
        {
            Console.WriteLine("输出Test1");
        }
        static void Test2()
        {
            Console.WriteLine("输出Test2");
        }
        static void Main(string[] args)
        {
            Action a = Test1;
            a += Test2;
            a += Test1;
            a();
            //Delegate[] delegates = a.GetInvocationList();//获取委托对象中包含的方法集合
            //foreach(var de in delegates)
            //{
            //    de.DynamicInvoke();//遍历实现方法
            //}
            Console.ReadKey();
        }
    }

其实由于委托是不可变的,所以为委托的调用列表添加2个方法后的结果其实是变量指向的一个全新的委托,最后再将这个新的委托赋值给我们创建的委托对象a

4.从委托移除方法

可以使用-=运算符从委托移除方法

与为委托增加方法一样,其实是创建了一个新的委托。新的委托是旧的委托的副本——只是没有了已经被移除方法的引用。

注意事项:1.如果在调用列表中的方法有多个实例,-=运算符将从列表最后开始搜索,并且移除第一个与方法匹配的实例。
2.试图删除委托中不存在的方法没有效果
3.试图调用空委托会抛出异常。可以通过把委托与null进行比较来判断委托的调用列表是否为空。如果调用列表为空,则委托是null。

5.匿名方法

匿名方法允许我们避免使用独立的具名方法,其实质就是在初始化委托时内联(inline)声明的方法。

使用地方:1.声明委托变量时作为初始化表达式。
2.组合委托时在赋值语句的右边。
3.为委托增加事件时在赋值语句的右边。
组成部分: delegate关键字+ (参数列表) +{语句块}

class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> a = delegate (int a1, int a2)
                {
                    return a1 + a2;
                };
            Console.WriteLine(a(2,3).ToString());
            Console.ReadKey();
        }
    }

6.Lambda表示

C#2.0引入了匿名方法。然而它的语法有一点麻烦,而且需要一些编译器已经知道的消息。C#引入了Lambda表达式,简化了匿名方法的语法,从而避免包含这些多余的信息。

从匿名方法转换到Lambda表达式。

1.删除delegate关键字
2.在参数列表和匿名方法主体之间放Lambda运算符=> .读作"goes to"。
例:

Mydel del=delegate(int x)  {return x+1;}//匿名方法
Mydel del=        (int x)=>{return x+1;}//Lambda表达式

我们还可以进一步简化Lambda表达式。
编译器可以从委托的声明中知道委托参数的类型,因此Lambda表达式允许我们省略类型参数

Mydel del=            (x)=>{return x+1;}//Lambda表达式

如果只有一个参数,我们可以省略周围的圆括号

Mydel del=            x=>{return x+1;}//Lambda表达式

最后 Lambda表达式允许表达式的主体是语句块或表达式。如果语句块包含了一个返回语句,我们可以将语句块替换为return 关键字后的表达式

Mydel del=            x=>       x+1;//Lambda表达式

基础概念差不多就这些了吧…如果有遗漏的或者哪里写错了请指出谢谢

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值