什么是委托?

一,什么是委托?

在MSDN中写着:delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。 

PS:针对这委托是类型安全和可靠的理解:委托本质是类,是强类型,.net下对象都是类型安全的(类型安全的原因:C#在编译期会检验类型,如果不一致则编辑器生成一个编译时错误)。

参照:http://bbs.csdn.net/topics/330140759

二,那可用于封装命名或匿名方法的引用类型怎么理解?

 委托:可以在不同对象之间传递方法,这个方法可以是命名方法,也可以是匿名方法。可以是静态方法,也可以是实例方法。而正是因为传的仅仅是方法名,看不到具体的实现,则这体现了封装的思想,并且委托的实现需要实例,同时证明委托也是引用类型。如下的例子:

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

namespace delegateDemo
{
    class Program
    {
        public delegate void delegateInt();
        static void Main(string[] args)
        {
            Test t = new Test();
            //实现静态方法委托,传入方法名即可
            delegateInt de = new delegateInt(Test.say);
            //实现实例委托,传入方法名
            delegateInt de2 = new delegateInt(t.say2);
            de();
            de2();
            Console.ReadKey();
        }
    }
    class Test
    {
        public static void say()
        {
            Console.WriteLine("我是委托");
        }
        public void say2()
        {
            Console.WriteLine("我是委托2");
        }
    }

}

 匿名实现委托

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

namespace delegateDe
{
    class Program
    {
        delegate void delegateNiName(string str);

        static void Main(string[] args)
        {
            delegateNiName DelA = new delegateNiName(Test.say);

            delegateNiName DelB = delegate(string s) { Console.WriteLine(s); };

            delegateNiName DelC = (x) => { Console.WriteLine(x); };

            // 实现委托
            DelA("我是静态实现委托");
            DelB("我是匿名实现委托1");
            DelC("我是匿名实现委托2");

            Console.ReadKey();
        }
    }
    class Test
    {
        public static void say(string s)
        {
            Console.WriteLine(s);
        }
    }

}

 三,delegate,event,Action<T> 和Func<T>又有什么区别:

1》先是event和delegate的区别:

1,事件是一种特殊的委托,或者说是受限制的委托,是委托一种特殊应用,只能施加+=,-=操作符。二者本质上是一个东西。

2,event只允许用add, remove方法来操作,这导致了它不允许在类的外部被直接触发,只能在类的内部适合的时机触发,委托可以在外部被触发。如下例子

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

namespace delegateDiff
{
    class Test
    {
        // 编译代码后,使用 Visual Studio 2010自带的ILDASM.EXE反编译(简称IL),可知道:NET将委托定义为一个密封类,派生自基类System.MulticastDelegate,
        //并继承了基类的三个方法
        public delegate void DelegateTest();

        public event DelegateTest EventIn; // 定义委托事件,这个EventIn只有委托的+=,或者-=,这个是一个特殊的委托
        public DelegateTest DelegateIn;

        public void Say()
        {
            if (this.EventIn != null)  //事件的触发,say方法被下面的main函数调用触发EventIn事件
            {
                this.EventIn();
            }

            if (this.DelegateIn != null)
            {
                this.DelegateIn();
            }
        }
    }
    class Program
    {
        static void EventTest()
        {
            Console.WriteLine("haha!我是事件");
        }

        static void DelegateTest()
        {
            Console.WriteLine("haha!我是委托");
        }

        static void Main(string[] args)
        {
            Test TestIn = new Test();
            TestIn.DelegateIn += DelegateTest;
            TestIn.EventIn += EventTest;

            //别人触发方法的实现,事件和委托都可以
            TestIn.Say();   

            //委托和事件的区别:委托可以自己触发实现,而事件则会报错
            TestIn.DelegateIn();
            // TestIn.EventIn();  // 事件触发会报错

            Console.ReadKey();
        }
    }
}

 2》Action<T>和Func<T>,则是.NET默认的委托类型,即是封装好的委托

1.Action<T>泛型Action<T>委托表示引用一个void返回类型的方法。

这个委托类存在16种重载方法。 例如Action<in T1,In T2>调用没有参数的方法

 Action<string> action = i => Console.WriteLine(i);
 action("Hello");

2.Func<T>

Func<T>调用带返回类型的方法。有16种重载方法。 例如Func<out TResult>委托类型可以调用带返回类型且无参数的方法,

Func<in T,out TResult>委托类型调用带有4个参数和一个返回类型的方法。

         //func和表达式的使用
            Expression<Func<int, bool>> ex = (i => i > 0);
            Func<int, bool> func = ex.Compile();
            var Test = func(5);                     //返回true

            //Func的定义和调用 
            Func<string, bool> funcT = (i => { i = "Hello"; Console.WriteLine(i); return false; });

            //Func的定义和调用,返回值类型自定义 
            Func<string, string> funcT1 = (i => { i = "Hello"; Console.WriteLine(i); return i; });
            var Te1 = funcT1("Hello");    //返回输入内容

            //Func的无参的时候的使用
            Func<bool> funcT2 = (() => { Console.WriteLine("Hello"); return false; });
            var Te = funcT2();   //返回false

            //Func的无参的时候的使用,返回值类型自定义
            Func<string> funcT3 = (() => { Console.WriteLine("Hello"); return "Hello"; });
            var Te3 = funcT3();         //返回输入内容


            if (funcT("Hello"))
            {
                Console.WriteLine("Hello");
            }
            else
            {
                Console.WriteLine("World");
            }
原文地址:https://www.cnblogs.com/May-day/p/6438523.html