C#中的委托

委托的定义

委托从字面上理解就是代理,类似于中介。

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

委托是一种引用类型,定义委托时与方法相似,但不能将其称为方法。

委托在使用时遵循三步走的原则,即定义/声明委托实例化委托调用委托

从数据结构来讲,委托是和类一样是一种用户自定义类型。

委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址

调用委托的时候,委托包含的所有方法将被执行。

委托是 C# 语言中的一个特色,通常将委托分为命名方法委托多播委托匿名委托,其中命名方法委托是使用最多的一种委托。

命名方法委托

定义/声明委托

在 C#语言中命名方法委托是最常用的一种委托,其定义的语法形式如下。

修饰符  delegate  返回值类型  委托名 ( 参数列表 );

从上面的定义可以看出,委托的定义与方法的定义是相似的。例如定义一个不带参数的委托,代码如下。

public delegate void MyDelegate();

实例化委托

在定义好委托后就到了实例化委托的步骤,命名方法委托在实例化委托时必须带入方法的具体名称。

实例化委托的语法形式如下。

委托名  委托对象名 = new 委托名 ( 方法/函数名 );
MyDelegate myDelegate = new MyDelegate(Method);

委托中传递的方法名既可以是静态方法的名称,也可以是实例方法的名称。

需要注意的是,在委托中所写的方法名必须与委托定义时的返回值类型和参数列表相同

调用委托

在实例化委托后即可调用委托,语法形式如下。

委托对象名 ( 参数列表 );

在这里,参数列表中传递的参数与委托定义的参数列表相同即可。

下面分别通过两个实例来演示在委托中应用静态方法实例方法的形式。

【实例 1】静态方法

若使用静态方法,在向委托中传递方法名时只需要用“类名.方法名”的形式,代码如下。

class Program
{
	//声明委托
    public delegate void MyDelegate();
    static void Main(string[] args)
    {
    	//实例化委托
        MyDelegate myDelegate1 = new MyDelegate(Test.SayHello);
        MyDelegate myDelegate2 = new MyDelegate(Test.SayHello);
        //调用委托
        myDelegate1();
        myDelegate2(5);
    }
}
class Test
{
    public static void SayHello()
    {
        Console.WriteLine("Hello Delegate!");
    }
    public static void PrintNum(int num)
    {
    	Console.WriteLine("{0}", num);
    }
}

执行上面的代码,结果如下:

Hello Delegate!
5

【实例 2】实例方法

实例方法需要通过类的实例来调用方法,即使用“new 类名 (). 方法名”的形式,代码如下。

class Program
{
	//声明委托
    public delegate void MyDelegate();
    static void Main(string[] args)
    {
    	//实例化委托
        MyDelegate myDelegate = new MyDelegate(new Test().SayHello);
        //调用委托
        myDelegate();
    }
}
class Test
{
    public void SayHello()
    {
        Console.WriteLine("Hello Delegate!");
    }
}

执行上面的代码,结果如下:

Hello Delegate!

除了使用匿名对象的方式调用方法以外,也可以先创建类的实例,再通过类的实例调用方法。

在了解了命名方法委托的写法以后,下面通过一个综合实例来演示命名委托的应用。

【实例 3】使用委托完成将图书信息按照价格升序排序的操作。

根据题目要求,先定义图书信息类,然后定义对图书价格排序的方法。图书信息类的代码如下。

class Book:IComparable<Book>
{
    //定义构造方法,为图书名称和价格赋值
    public Book(string name,double price)
    {
        Name = name;
        Price = price;
    }
    //定义图书名称属性
    public string Name { get; set; }
    //定义图价格属性
    public double Price { get; set; }
    //实现比较器中比较的方法
    public int CompareTo(Book other)
    {
        return (int)(this.Price - other.Price);
    }
    //重写ToString方法,返回图书名称和价格
    public override string ToString()
    {
        return Name + ":" + Price;
    }
    //图书信息排序
    public static void BookSort(Book[] books)
    {
        Array.Sort(books);
    }
}

在 Main 方法中定义委托调用图书排序的方法,代码如下。

class Program
{
    //定义对图书信息排序方法的委托
    public delegate void BookDelegate(Book[] books);
    static void Main(string[] args)
    {
    	//实例化委托
        BookDelegate bookDelegate = new BookDelegate(Book.BookSort);
        Book[] book = new Book[3];
        book[0] = new Book("计算机应用", 50);
        book[1] = new Book("C# 教程", 59);
        book[2] = new Book("VS2015应用", 49);
        //调用委托
        bookDelegate(book);
        //遍历输出
        foreach(Book bk in book)
        {
            Console.WriteLine(bk);
        }
    }
}

执行上面的代码,效果如下:

VS2015应用:49
计算机应用:50
C# 教程:59

从上面的执行效果可以看出,通过委托调用的图书排序方法 (BookSort) 按照图书价格升序排列了图书信息。

需要注意的是,由于 Book[] 数组是引用类型,因此通过委托调用后其值也发生了相应的变化,即 book
数组中的值已经是完成了排序操作后的结果。

C#多播(组播)委托

在 C# 语言中多播委托是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符或者减号运算符来实现添加或撤销方法。只有相同类型的委托可被合并。

在现实生活中,多播委托的实例是随处可见的,例如某点餐的应用程序,既可以预定普通的餐饮也可以预定蛋糕、鲜花、水果等商品。

在这里委托相当于点餐平台,每一个类型的商品可以理解为在委托上注册的一个方法。

下面通过实例来演示多播委托的应用。

【实例】模拟点餐平台预定不同类型的商品。

根据题目要求,在实例中分别预定快餐、蛋糕、鲜花三类商品,代码如下。

class Program
{
    //定义购买商品委托
    public delegate void OrderDelegate();
    static void Main(string[] args)
    {
        //实例化委托
        OrderDelegate orderDelegate = new OrderDelegate(Order.BuyFood);
        //向委托中注册方法
        orderDelegate += Order.BuyCake;
        orderDelegate += Order.BuyFlower;
        //调用委托
        orderDelegate();
    }
}
class Order
{
    public static void BuyFood()
    {
        Console.WriteLine("购买快餐!");
    }
    public static void BuyCake()
    {
        Console.WriteLine("购买蛋糕!");
    }
    public static void BuyFlower()
    {
        Console.WriteLine("购买鲜花!");
    }
}

执行上面的代码,效果如下:

购买快餐!
购买蛋糕!
购买鲜花!

如果已经购买了鲜花,在未调用委托时也可以撤销,在委托注册方法时使用 -= 操作符即可。

撤销购买鲜花操作的代码如下。

orderDelegate -= Order.BuyFlower;

如果添加了上述代码,则执行效果中就取消了购买鲜花的操作。

在使用多播委托时需要注意,在委托中注册的方法参数列表必须与委托定义的参数列表相同,否则不能将方法添加到委托上。

匿名委托

在 C# 语言中匿名委托是指使用匿名方法注册在委托上,实际上是在委托中通过定义代码块来实现委托的作用,具体的语法形式如下。

//1. 定义委托
修饰符  delegate  返回值类型  委托名 ( 参数列表 );

//2. 定义匿名委托
委托名  委托对象 = delegate
{
    //代码块
};

//3. 调用匿名委托
委托对象名 ( 参数列表 );

通过上面 3 个步骤即可完成匿名委托的定义和调用,需要注意的是,在定义匿名委托时代码块结束后要在 {} 后加上分号

【实例】使用匿名委托计算长方形的面积。

class Program
{
	//1.声明委托
    public delegate void AreaDelegate(double length, double width);
    static void Main(string[] args)
    {
        Console.WriteLine("请输入长方形的长:");
        double length = double.Parse(Console.ReadLine());
        Console.WriteLine("请输入长方形的宽:");
        double width = double.Parse(Console.ReadLine());
        //2.定义匿名委托
        AreaDelegate areaDelegate = delegate
        {
            Console.WriteLine("长方形的面积为:" + length * width);
        };
        //3.调用匿名委托
        areaDelegate(length, width);
    }
}

执行上面的代码,效果如下:

请输入长方形的长:
10
请输入长方形的宽:
5
长方形的面积为:50

从上面的执行效果可以看岀,在使用匿名委托时并没有定义方法,而是在实例化委托时直接实现了具体的操作。

由于匿名委托并不能很好地实现代码的重用,匿名委托通常适用于实现一些仅需要使用一次委托中代码的情况,并且代码比较少
————————————————
版权声明:本文为CSDN博主「小小小陆」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luan0125/article/details/122957212

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值