zoukankan      html  css  js  c++  java
  • 委托学习体会

    1. 委托简介   

    2. 委托组合与分解   

    3. 泛型委托   

    4.匿名方法和Lambda表达式   

    1.委托简介

    说来惭愧,做开发也有好几年了,但对委托依然一知半解,项目中也很少用到,这周在家仔细的看了下,写了点心得体会。

    .net framework 基类库大量地使用了委托,那么什么是委托呢?

    大家熟悉的常用数据类型(如int)的使用方法:先定义一个变量,然后给他赋值,如

    Int I;//定义变量

    I=100;//给变量赋值

    类似的委托也可以看成是一种数据类型,可以用于定义变量,但它所定义的变量能接收的值只能是一个方法。

    举个例子FirstDelegateExample:

    //类MathOpt,定义了一下Add方法

    Public cass MathOpt

    {

    Public int Add(int argument1,int argument2)

    {

        Return argument1+argument2;

    }

    }

    //定义一个委托数据类型MathOptDelegate

    Public delegate int MathOptDelegate(int value1,int value2)

    上述委托跟前面定义的Add方法,两者都接收两个int参数,返回一个int数值,它们是不是”长得很像”,确实,这种相似不是偶然的

    定义好委托数据类型后,就可以如此使用它。

    MathOptDelegate oppDel; //定义此委托类型变量

    MathOpt obj=new MathOpt();//实例化类

    oppDel=obj.Add; //委托变量接收一个方法, 注意add后面没有括号

    oppDel(1,2); //赋值之后委托变量可以当成普通方法一样使用,等同于Add(1,2)

    此项目可以得出一个直观印像:委托可以看成是一个方法的”容器”,将某一具体的方法”装入”后,就可以把它当成方法一样使用。

    那么是不是所有方法都可以赋值给oppDe变量呢?

    仔细看MathOptDelegate定义语句,只能接收这样的方法,拥有两个int参数,并且返回值也是int。

    所以只要满足上述要求,不管其名字如何,也不管它是静态还是实例,都可以赋值给oppDel,定义委托类型时对方法的要求被称为方法的”签名”

     示例项目DynamicInvokeMethodForCS,用户输入两个操作数,再选择运算方法,程序即可算出结果。这个示例的关键之处在于它使用委托在运行时动态的调用不同方法

    示例程序UseDelegateForm:点击从窗体按钮,主窗体会记录下对按钮的单击次数,这个示例关键在于主从窗间信息的传送用到了ShowInfoDelegate

    2.委托组合与分解

    从上面介绍的内容可知,委托变量可以引用某一方法,调用它就相当于调用这个方法

    仔细想想,是不是会有以下疑惑:

    如果委托仅仅是方法调用的另一种方式,那何必多此一举引入委托这一特性?直接调用方法不是更简洁明了?

    其实委托不仅可以引用一个方法,还可以组合多个方法并批量执行它们,看以下示例

        delegate void MyDelegate(string s);

        class Program

        {

            static void Main(string[] args)

            {

                MyDelegate a,b,c,d;

                a=MyClass.Hello;

                Console.WriteLine("调用托变量a");

                a("a");

     

                b = MyClass.GoodBye;

                Console.WriteLine("调用托变量b");

                b("b");

     

                c = a + b;

                Console.WriteLine("调用托变量c");

                c("a+b");

     

                d = c - a;

                Console.WriteLine("调用托变量d");

                d("c-a");

     

                Console.ReadKey();

            }

        }

        class MyClass

        {

            public static void Hello(string s)

            {

                Console.WriteLine("您好,{0}", s);

            }

            public static void GoodBye(string s)

            {

                Console.WriteLine("再见,{0}", s);

            }

        }

    执行结果:

    上述代码委托变量c组合了委托变量a+b,因而拥有了两个方法,当执行c(“a+b”)时将导致MyClass类的两个静态方法都被执行

    像这样的委托变量称为”多路委托变量”

    可以用加法运算符来给合单个委托变量为多路委托变量,同样的用减法运算符从一个多路委托变量中除移某个委托变量

    委托之所以有这种特性,是因为它内部可以包含多个方法引用,这些方法引用被称为”委托调用列表”

    3.泛型委托

    首先通过一个示例

      class Program

        {

            static void Main(string[] args)

            {

                MyGenericDelegate<int> del = MyFunc;

                Console.WriteLine(del(10));

                Console.ReadKey();

     

            }

            static int MyFunc(int value)

            {

                return value;

            }

        }

        public delegate T MyGenericDelegate<T>(T obj);

    泛型委托跟普通委托类似,不同之处在于使用泛型委托时需要指定泛型参数,除此之外没任何神秘之处。

    为了方便开发,.NET基类库针对在实际开发中最常用的情形提供了几个预定义好的委托

    Func系列委托用于引用一个有返回值的方法

    Func委托声明的最后一个泛型参数是委托所接收方法的返回值类型,前面的泛型类型参数(如果有的话)就是委托所接收方法的形参类型

    示例如下:

    class Program

        {

            static void Main(string[] args)

            {

                Func<int, int, long> func = Add;

                Console.WriteLine(func(10, 20));

     

                Func<string, string, string> func1 = LinkStr;

                Console.WriteLine(func1("你好:", "鱼"));

                Console.ReadKey();

            }

            static long Add(int x, int y)

            {

                return x + y;

            }

            static string LinkStr(string a, string b)

            {

                return a + b;

            }

     

        }

     还有另外常用的预定义委托,大家自行查阅资料

    Action系列委托:接收返回为void的方法

    Predicate委托:引用一个返回bool值的方法

     4.匿名方法和Lambda表达式

    总结一下上面的使用委托步骤

    1.定义委托类型

    2.定义一个或多个符合委托类型要求的方法

    3.定义委托类型的变量

    4.将2中定义的方法引用”挂接”到3步中定义的变量,构建一个委托调用列表

    5.能过委托变量间接调用方法

    上述步骤是不是很烦锁,基于上述简化开发的考虑,C#引入了匿名方法和Lambda表达式

    示例代码如下注意加粗字:

        class Program

        {

            static void Main(string[] args)

            {

                AddDelegate del = delegate(int i, int j)

                {

                    return i + j;

                };

                Console.WriteLine(del(10, 20));

                Console.ReadKey();

            }

        }

        public delegate int AddDelegate(int i,int j);

    匿名方法其实是将方法定义与委托变量赋值两个步骤合在一起,从而省掉了单独定义一个方法的麻烦

    上面的代码如果用Lambda表达式,可以如此简化

        class Program
        {
            static void Main(string[] args)
            {
                SomeDelegateType del2 = argument => { return argument.ToString(); };
                Console.WriteLine(del2(10));
                Console.ReadKey();
            }
        }
        public delegate string SomeDelegateType(int argument);

    Lambda表达式其实就是匿名方法的进一步简化,可以用于定义一个匿名函数,并将其传送给一个委托变量

    Lambda有两种基本格式

    1.(input parameter)=>表达式

    2.(input parameter)=>{语句1;语句2;}

    1)只有一个参数时,括号是可选的,Lambda表达式只有一条return语句时,return关键字也可省

    Func<int,bool> del1=(x)=>{return x>0};

    可以简化为

    Func<int,bool> del1=x=>{x>0};

    2)两个或更多输入参数由逗号分隔

    Func<int,int,bool> del2=(int x,int y)=>{return x==y};

    3)没有输入参数时,直接使用一个空的括号()

    Action del4=()=>{Console.WriteLine("No argument");};

  • 相关阅读:
    第六周
    第五周
    第四周
    第二周学习记录
    实验一 Linux初步认识
    java实验四
    java实验三
    为什么无密码认证能够有效
    关于父元素,子元素,同级元素的DOM操作技巧
    高效设计构建软件的十三条建议
  • 原文地址:https://www.cnblogs.com/75115926/p/3019712.html
Copyright © 2011-2022 走看看