C# 委托详解汇总

委托的存在是因为,我们有时候需要将一个函数作为另一个函数的参数,这时就要用的委托(Delegate)机制,,,

委托用关键字delegate声明,他实际上定义了一种“函数类型”,明确规定了函数参数类型和返回值类型。(即无参数无返回值的委托,只能接受无参数无返回值的方法,反之亦然,,)

声明委托
在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字段和方法组成的,然后使用这个类实例化对象。在我们使用委托的时候,也需要经过这两个阶段,首先定义委托,告诉编译器我们这个委托可以指向哪些类型的方法,然后,创建该委托的实例

定义委托的语法如下:
delegate void MethodInvoker(int x);
定义了一个委托叫做MethodInvoker,这个委托可以指向什么类型的方法呢?

这个方法要带有一个int类型的参数,并且方法的返回值是void的。
定义一个委托要定义方法的参数和返回值,使用关键字delegate定义。
定义委托的其他案例:
delegate double TwoLongOp(long first,long second);
delegate string GetAString();


.NET编译器严格检查函数类型和未做的类型是否匹配,只有完全匹配才能进行转换转换之后的委托实例作为参数,传递给调用它的函数,
利用委托可以实现以函数为参数,提高程序的通用性,委托用关键字的delegate声明,实际上创建,一种委托相当于创建一个从System.Delegate派生出来的类,类中有一个调用列表,列表中包含着委托函数的引用,与c++的函数指针相比委托是一个在类型安全的方式。

小例:

using System;

namespace 委托
{
    class Program
    {
        //定义委托   返回值string类型,无参数
        private delegate string GetAString();

        static void Main(string[] args)
        {
            //======================构造函数使用委托====================
            int x = 410;
            //使用委托声明实例  str指向了Tostring方法
            GetAString str = new GetAString(x.ToString);

            string res = str();  //委托类型调用方法

            Console.WriteLine(res);

            //======================直接赋值法使用委托====================
            GetAString str1 = x.ToString;
            string res1 = str1.Invoke();   //通过invoke方法调用str1所引用的方法
            //string res1 = str1(); //是一样的,
            Console.WriteLine(res);


            //示例:使用委托作为参数
            GetAString getastring = GetName;
            Console.WriteLine(getastring());

            getastring = GetAge;
            Console.WriteLine(getastring());

            Console.ReadKey();
        }
        static string GetName()
        {
            string str = "这是GetName方法";
            return str;
        }
        static string GetAge()
        {
            string str = "这是GetAge方法";
            return str;
        }
    }
}


系统预定义的委托:
除了我们自己定义的委托之外,系统还给我们提供过来一个内置的委托类型,Action和Func
Action委托引用了一个void返回类型的方法,T表示方法参数,先看Action委托有哪些

Action委托示例

namespace Action委托
{
    class Program
    {
        static void Main(string[] args)
        {
            //系统内置的一个委托类型,它指向一个没有返回值,没有参数的方法
            Action method1 = Show;
            method1();

            //利用泛型,定义没有返回值,带参数的委托
            Action<string> method2 = Show;
            method2("CZHENYA");

            //系统会自动识别重载方法,,Action可以通过泛型来添加参数(最多支持16个参数),但是一定没有返回值
            Console.ReadLine();
        }

        static void Show()
        {
            Console.WriteLine("Hello Czhenya");
        }

        static void Show(String name)
        {
            Console.WriteLine("HELLO"+name);
        }
    }
}

Func引用了一个带有一个返回值的方法,它可以传递0或者多到16个参数类型,和一个返回类型

//func委托实例
namespace Func委托
{
    class Program
    {
        static void Main(string[] args)
        {

            //func 中的泛型是指定的方法的返回值类型,,
            Func<int> method = Show1;
            Console.WriteLine("方法的返回值是:"+ method());

            //func 中的泛型是最后一个类型必须是函数的返回值类型,前面的是方法参数类型可以输入(0-16)
            Func<int,string> method1 = Show2;
            Console.WriteLine(method1(20));
            Console.ReadKey();
        }

        static int Show1()
        {
            return 111;
        }

        static string Show2(int age)
        {
            Console.WriteLine(age);
            return "Czhenya";
        }
    }
}

多播委托

多播委托:我们把包含多个函数的委托称为多播委托(Muiticast Delegate),所有被委托函数的引用都存储在多播委托类的调用列表中,当调用多播委托时,会按顺序依次调用列表中的所有函数。
向多播委托中注册函数的语法为:
通过+=运算符向多播委托中注册函数
从多播委托中删除函数的语法:使用-=运算符,,
注:多播委托只能得到调用的最后一个方法的结果,一般多播委托的返回值只能是void ,,,

namespace 多播委托
{
    class Program
    {
        static void Main(string[] args)
        {
            //多播委托   
            Action method = Text1;
            method += Text2;
            //method();
            //method -= Text1;    
            //当委托没有指向任意一个方法的时候,会报出异常,,,

            //获得委托中的所有方法
            Delegate[] delegates = method.GetInvocationList();
            //遍历出来,挨个调用
            foreach (Delegate item in delegates)
            {
                //item();
                item.DynamicInvoke();
            }

            Console.ReadKey();
        }

        static void Text1()
        {
            Console.WriteLine("Text1");
        }
        static void Text2()
        {
            Console.WriteLine("Text2");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈言必行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值