C#基础---委托的使用

一:什么是委托

      委托是一种定义方法签名的类型当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。您可以通过委托实例调用方法。委托是一个引用类型,所以它具有引用类型所具有的通性。它保存的不是实际值,而是保存对存储在托管堆(managed heap)中的对象的引用。 委托可以引用静态方法和非静态方法。

通俗的理解是,委托其实可以是一种简单的约束,好比在工作上我声明了一个委托人A, A同时可以接受(人力资源,后勤公务)两个参数,那么只要是有人想处理(人力资源,后勤)方面的事情,都可以去注册到委托人A上,A有能力接受这些方法,然后去处理。

二:委托的声明

声明委托可以通过delegate来声明,委托可以依赖于一个类,也可以依赖于一个namespace间。即 在类里面声明和在类外面声明。其中delegate可以有返回类型和非返回类型,其中delegate也支持泛型。

public delegate double AddNum(double num1,double num2);
public delegate void ShowMsg(string str);

  三: 委托的使用

     1. 基本使用:下面是一个计算方法,声明了一个委托CalculatorDelegate,然后在Main方法里面先后注册了AddNum,和SumNum方法,注册的方法必须与委托的参数以及返回类型相符合,否者将会提示【委托与注册方法不匹配的提示】对于这块是直接编译无法通过的。委托如果被注册了多个方法,称为多播。对于多播,调用委托后,按照注册顺序执行。不过对于有返回值的方法,将返回最后注册的方法执行后的返回值。

Notes:第一次注册方法的时候可以使用【=注册】或者【new CalculatorDelegate(方法名) 】,后面添加方法用【+】,取消注册方法用【-】

运行代码和运行结果如下图:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpongeBobCoder.Delegate
{
    public delegate double CalculatorDelegate(double num1, double num2); // 委托,声明在类之外

    public class Program
    {
        public static double AddNum(double num1, double num2)
        {
            Console.WriteLine("Sum={0}", num1 + num2);
            return num1 + num2;
        }

        public static double SubNum(double num1, double num2)
        {
            Console.WriteLine("Sub={0}", num1 - num2);
            return num1 - num2;
        }

        public static void Main(string[] args)
        {
            CalculatorDelegate calculatorDel = AddNum; // 目前为单播
            Console.WriteLine("委托一个方法的结果为:{0}", calculatorDel(1, 2));
            calculatorDel += SubNum; // 目前是多播
            Console.WriteLine("委托两个方法的结果为:{0}", calculatorDel(1, 2));
            Console.ReadKey();
        }
    }
}

    2. 委托注册方法的几种形式:除了上面的方式,其实委托的注册方法还支持Linq方法,匿名方法。其实在Linq中也大量的委托,比如在使用List<T>.where(),List<T>.sort()这些方法的时候其实里面就运用的大量的委托。其实可以理解为就是委托的缩影。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpongeBobCoder.Delegate
{
    public delegate double CalculatorDelegate(double num1, double num2); // 委托

    public class Program
    {
        public static void Main(string[] args)
        {
            CalculatorDelegate calculatorDel = delegate(double x, double y) //等效于AddNum方法
            {
                return x + y;
            };
            Console.WriteLine("委托一个方法的结果为:{0}", calculatorDel(1, 2));

            calculatorDel += (x, y) => // 等效于SumNum方法
            {
                return x - y;
            };

            Console.WriteLine("委托两个方法的结果为:{0}", calculatorDel(1, 2));
            Console.ReadKey();
        }
    }
}

     3. 小添加: 其实在.net框架提供了自带的委托. Action<T>,Func<T,out Result>。Action是无返回值泛型委托,Func是有返回值的泛型委托【out Result就是返回值,不过使用的时候不是要传入一个out参数,对于Action<T,T,out Result>,其实就是传入2个参数。】代码如下:

          Notes:注意Func<>三个参数,可是AddNum只有两个,其实第三个就是对应的返回值,这里有别于我们前面说的委托,希望大家注意.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SpongeBobCoder.Delegate
{
    public class Program
    {
        private static void ShowMsg(string str)
        {
            Console.WriteLine(str);
        }

        private static double AddNum(double num1, double num2)
        {
            return num1 + num2;
        }

        public static void Main(string[] args)
        {
            Action<string> action = ShowMsg;
            action("Action委托好用!");
            Func<double, double, double> func = AddNum; // Notes
            Console.WriteLine("Func委托真好用,两数之和为:{0}", func(1, 2));
            Console.ReadKey();
        }
    }
}

四:总结

因为最近在接触Silverlight,事件委托以后会不断接触。所以这两天看了一下事件委托的知识,并写博客记录一下。有什么理解不对,描述不对的还请各位博友指点指点。下篇会更新事件的使用。

   

时间: 2024-10-21 11:31:37

C#基础---委托的使用的相关文章

[C#基础] 委托

什么是委托 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性. 使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法. 委托的定义 通常一个委托被定义为 public delegate void CalcDelegate(int x, int y); 关键字de

C#基础——委托

以下所写是个人对委托的理解,为了加深对委托的理解和记忆,特地写下来. 委托的介绍: 委托和事件是一对好搭档,事件在之后的文章中做介绍.C#中常使用委托做回调. 委托其实是一个类,在编译之后的编译文件中可以看到,委托的类型是class. 1.声明委托 使用关键字:delegate, 如下所示:这里声明了一个没有返回值的委托. public delegate void ConsloleWrite(string str); 2.使用委托 public class Program { static vo

C#基础-委托与事件

委托 delegate是申明委托的关键字 返回类型都是相同的,并且参数类型个数都相同 委托声明 delegate double DelOperater(double num1, double num2); 实例化委托对象 class Program { static void Main(string[] args) { DelOperater delOp = new DelOperater(Add); } static double Add(double a,double b) { return

C#基础---事件的使用

一:什么是事件     事件是可以被控件识别的操作,如按下确定按钮,选择某个单选按钮或者复选框.每一种控件有自己可以识别的事件,如窗体的加载.单击.双击等事件,编辑框(文本框)的文本改变事件,等等.事件在桌面应用程序里面无处可见,比如winform,WPF...,其次事件是基于委托而产生的. 二:事件的基本使用 1.事件的声明: 其实和委托一样只是多了一个Event而已.ShowMsg 就具备了ShowMsgHandler的功能. Notes: 1. 委托可以依赖于一个类或者一个域名空间(C#基

说说委托那些事儿

委托基础 委托是个啥? 很多人第一反映可能是"函数指针",个人觉得"函数指针"是委托实例 委托的定义类似interface,是一种方法的"规范"或者说"模版",用来规范方法的"行为",以便将方法作为参数传递 public delegate void MyDelegate(); 这样便定义了一个无参无返回值的委托,要求此委托的实例必须是无参无返回值的方法 public class MyClass { publ

C#系列文章之事件

文件涉及的内容: 设计公开事件类型 编译器如何实现事件 设计侦听事件的类型 显式实现事件 事件:定义了事件成员的类型允许类型通知其他对象发生特定的事情. CLR事件模型以委托为基础,委托是调用回调方法的一种类型安全的方式,对象凭借调用方法接收他们订阅的通知. 定义了事件成员的类型要求能够提供以下功能: 方法能登记它对事件的关注 方法能注销它对事件的关注 事件发生时,登记的方法将收到通知 本文章以一个电子邮件应用程序为例.当电子邮件到达时,用户希望将邮件转发给传真机或寻呼机进行处理.先设计Main

第五节:使用反射发现类型成员

到目前为止,本章的重点一直放在发射机制中用于构建动态可扩展应用程序所需的那些方面,包括程序集加载.类型发现以及对象构造.为了获得较好的性能和编译时的类型安全性,应尽量避免使用发射.在动态可扩展应用程序的情况下,构造好一个对象之后,宿主代码一般要将对象转型为编译时已知的一个接口或者基类.这样一来,访问对象的成员时,就可以获得较高的性能,而且可以确保编译时的类型安全性. 在本章剩余的部分,我们将从其他角度讨论反射,目的是发现并调用类型的成员,这种发现并调用类型成员的能力一般用于开发工具和实用程序,他

event 关键字

event(C# 参考) event 关键字用于在发行者类中声明事件.下面的示例演示如何声明和引发将 EventHandler 用作基础委托类型的事件. C# public class SampleEventArgs { public SampleEventArgs(string s) { Text = s; } public String Text {get; private set;} // readonly } public class Publisher { // Declare the

C#6.0语言规范(十) 类

类是可以包含数据成员(常量和字段),函数成员(方法,属性,事件,索引器,运算符,实例构造函数,析构函数和静态构造函数)和嵌套类型的数据结构.类类型支持继承,这是一种派生类可以扩展和专门化基类的机制. 类声明 一个class_declaration是type_declaration(类型声明,声明一个新的类). 1 class_declaration 2 : attributes? class_modifier* 'partial'? 'class' identifier type_paramet