• 什么是委托?


    一,什么是委托?

    在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");
                }
  • 相关阅读:
    python:封装连接数据库方法
    Python:self理解
    python:pytest优秀博客
    python:pytest中的setup和teardown
    python:单元测试框架pytest的一个简单例子
    java中的static关键字解析
    浅谈Java中的final关键字
    SpringMVC+Spring+Mybatis框架集成
    Mybatis学习总结(四)——输入映射和输出映射
    Mybatis学习总结(三)——SqlMapConfig.xml全局配置文件解析
  • 原文地址:https://www.cnblogs.com/May-day/p/6438523.html
Copyright © 2020-2023  润新知