C#委托

1.什么是委托

==理解委托最快的方式是把它看成一个类型安全的,面向对象的c++h函数指针!==

2.委托的概述

可以通过以下操作来使用委托:
1. 声明一个委托类型,委托声明看上去和方法声明类似,只是没有实现块。
2. 使用该委托类型声明一个委托变量。
3. 创建委托类型的对象,把它赋值给委托变量。新的委托对象包括指向某个方法的引用,这个方法和第一步定义的签名和返回类型一致。
4. 你可以选择为委托对象增加其他方法,这些方法必须与第一步中定义的委托类型有相同的签名和返回类型。
5. 在代码中你可以像调用方法一样调用委托,在调用委托的时候,其包含的每一个方法都会被执行。

委托和类一样,是一种用户自定义类型,但类表示的是数据和方法的集合,而委托则持有一个或多个方法,以及一系列预定义操作。
可以把delegate看作一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型。
- 方法的列表成为调用列表
- 委托保存的方法可以来自任何类和结构,只要它们在下面两点匹配:
- - 委托的返回类型。
- - 委托的签名(包括ref和out修饰符)。
- 调用方法中的方法可以是实例方法也可以是静态方法。
- 在调用委托的时候,会执行其调用列表中的所有方法。

delegate void MyDel (int x);
  • delegate:关键字
  • void:返回类型
  • MyDel:委托类型名
  • int x:签名
delegate void MyDel(int x);//声明委托类型
MyDel delVar,dVar;//创建两个委托变量

delVar=new MyDel(myInstObj.MyM1);//创建委托并保存引用
dVar=new MyDel(SClass.OtherM2);

除了为委托分配内存,创建委托对象还会把第一个方法放入委托的调用列表。

也可以使用快捷语法

MyDel delVar=myInstObj.MyM1;

3.组合委托

委托可以使用额外的运算符来“组合”。这个运算最终会创建一个新的委托,其调用列表连接了作为操作数的两个委托的调用列表副本。

例如,如下代码创建了3个委托,第3个委托由前两个委托组合而成

MyDel delA=myInstObj.MyM1;
MyDel delB=SClass.Other2;

MyDel delC=delA+delB;
委托并没有被修改,委托是恒定的,委托对象被创建后不能再被改变。

4.为委托添加和移除方法

MyDel delVar=inst.MyM1;//创建并初始化
delVar+=SCl.m3;//增加方法
delVar+=X.Act;
delVar-=SCl.m3;//从委托移除方法

在使用+=运算符时,实际发生的是创建了一个新的委托,其调用列表是左边的委托加上右边方法的组合。然后将这个新的委托赋值给delVar。而移除也是创建了一个新的委托,新的委托是旧的副本——只是没有了被移除方法的引用。

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

5.委托的实例

delegate void PrintFunction();
class Test
{
    public void Print1(){
        Console.WriteLine("111");
    }
    public static void Print2(){
        Console.WriteLine("222");
    }
    class Program{
        static void main(){
            Test t=new Test();
            PrintFunction pf;
            pf=t.Print1();
            //给委托增加三个另外的方法
            pf+=Test.Print2;
            pf+=t.Print1();
            pf+=Test.Print2();

            if(pf!=null)
                pf();
            else
                Console.WriteLine("444");
        }
    }
}
输出:111
      222
      111
      222

6.调用带返回值的委托

如果委托有返回值并且在调用列表中有一个以上的方法,会发生下面的情况:
- 调用列表中最后一个方法返回的值就是委托调用返回的值。
- 调用列表中所有其他方法的返回值都会被忽略。

delegate int MyDel();
class MyClass{
    int IntValue=5;
    public int Add2(){IntValue+=2;return IntValue;}
    public int Add3(){IntValue+=3;return IntValue;}
}
class Program{
    static void Main(){
        MyClass mc=new MyClass();
        MyDel mDel=mc.Add2;
        mDel+=mc.Add3;
        mDel+=mc.Add2;
        Console.WriteLine("Value:{0}",mDel());//调用委托并使用返回值
    }
}
输出:Value:12

7.调用带引用参数的委托

如果委托有引用参数,参数值会根据调用列表中的一个或多个方法的返回值而改变。
- 在调用委托列表中的下一个方法时,参数的新值会传给下一个方法。

delegate void MyDel(ref int x);
class MyClass{
    public int Add2(ref int x){x+=2;}
    public int Add3(ref int x){x+=3;}
    static void Main(){
        MyClass mc=new MyClass();
        MyDel mDel=mc.Add2;
        mDel+=mc.Add3;
        mDel+=mc.Add2;
        int x=5;
        mDel(ref x);
        Console.WriteLine("Value:{0}",x);//调用委托并使用返回值
    }
}
输出:Value:12

8.匿名方法

==匿名方法是在初始化委托时内联声明的方法==

我们可以在如下地方使用匿名方法:
- 声明委托变量时作为初始化表达式。
- 组合委托时在赋值语句的右边。
- 为委托增加事件时在赋值语句的右边。
- 外围作用域的变量叫做外部变量。
- 用在匿名方法实现代码中的外部变量成为被方法捕获。

匿名方法的语法
  1. 返回类型
delegate int OtherDel(int InParam);
OtherDel del =delegate(int x){
    return x+20;//返回一个Int值
};//记得分号
  1. 参数
    参数列表可以为空,条件如下:
    • 委托的参数列表不包含任何out参数。
    • 匿名方法不使用任何参数。
  2. params参数
    • 委托类型声明指定最后一个参数为params类型的参数。
    • 然而,匿名方法参数列表忽略params关键字。(省略)

9.Lambda表达式

C#2.0引入了匿名方法,C#3.0引入了Lambda表达式,简化匿名方法的语法

我们可以通过以下步骤把你那个方法转换成Lambda表达式
- 删除delegate关键字
- 在参数列表和匿名方法主体之间放Lambda运算符=>读作goes to
- Lambda表达式允许我们省略类型参数,如le2
- 如果只有一个隐式类型参数,我们可以省略圆括号,如le3
- - 带有类型的参数列表称为显式类型
- - 省略类型的参数列表称为隐式类型
- 可以将语句块替换为return关键字后的表达式,如le4
- Lambda表达式参数列表中的参数必须在参数数量,类型和位置上与委托相匹配
- 如果没有参数,必须使用空括号

MyDel del=delegate(int x){return x+1;};//匿名方法
MyDel le1=(int x)=>{return x+1;};//Lambda表达式
MyDel le2=(x)=>{return x+1;};//Lambda表达式
MyDel le3= x=>{return x+1;};//Lambda表达式
MyDel le4=x=>x+1;//Lambda表达式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# 委托(Delegate)是一种类型,它可以用于封装一个或多个方法,使其可以像其他对象一样传递、存储和调用。委托在事件处理、多线程等方面有着广泛的应用。 C# 委托的声明方式与方法类似,可以带有参数和返回值类型,例如: ```csharp public delegate int Calculate(int a, int b); ``` 上面的代码声明了一个名为 `Calculate` 的委托类型,它包含两个 `int` 类型的参数并返回一个 `int` 类型的值。接下来可以使用这个委托类型来封装一个或多个方法。 委托的使用步骤如下: 1. 声明委托类型 ```csharp public delegate void MyDelegate(string message); ``` 2. 定义委托变量 ```csharp MyDelegate myDelegate; ``` 3. 实例化委托变量 ```csharp myDelegate = new MyDelegate(MethodA); ``` 4. 调用委托 ```csharp myDelegate("Hello"); ``` 完整的示例代码如下: ```csharp using System; namespace DelegateDemo { public delegate void MyDelegate(string message); class Program { static void Main(string[] args) { MyDelegate myDelegate; myDelegate = new MyDelegate(MethodA); myDelegate += new MyDelegate(MethodB); myDelegate("Hello"); } static void MethodA(string message) { Console.WriteLine("MethodA: " + message); } static void MethodB(string message) { Console.WriteLine("MethodB: " + message); } } } ``` 上面的代码定义了一个名为 `MyDelegate` 的委托类型,包含一个 `string` 类型的参数并返回一个 `void` 类型的值。在 `Main` 方法中,首先将 `myDelegate` 委托变量实例化为 `MethodA` 方法,然后再将其实例化为 `MethodB` 方法。最终调用 `myDelegate` 委托变量时,将会依次调用 `MethodA` 和 `MethodB` 方法。 除了以上示例中的简单委托,还有多播委托、泛型委托、匿名委托等更加高级的委托用法,可以根据具体需求选择使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值