委托的使用 - 浅谈

系统 1816 0

一,声明委托

  对于委托,定义它就是要告诉编译器,这种类型的委托表示哪种类型的方法.然后,必须创建该委托的一个或多个委托实例,编译器将在后台创建表示该委托的一个类.

  因为定义委托基本上是定义一个新类,所以可以在定义类的任何相同地方定义委托.

  在 术语 方面,和"类,对象"不同."类"表示的是较为广义的定义,"对象"表示类的实例.但是委托只有一个术语,在创建委托实例时,所创建的 委托的实例 仍然称为 委托 .

  如下显示委托的声明方式:

      //声明委托.

private delegate string GetAString();


    

 

二,使用委托

  如下例子:

      
        1
      
      
        int
      
       x = 
      
        5
      
      
        ;


      
      
        2
      
      
        //
      
      
        通过委托的方式.
      
      
        3
      
       GetAString stringMethod = 
      
        new
      
      
         GetAString(x.ToString);


      
      
        4
      
       Console.WriteLine(stringMethod());  
    

  也可以使用 委托推断 ,只需将地址传递给委托类型的变量(在后台,C#编译器会做同样的处理,即会在后台创建一个委托实例 " new GetAString(x.ToString)"):

      
        1 
        
          //
          
            使用委托推断,只需将地址传递给委托实例. 
            
              2 GetAString secondMethod = x.ToString;
            
          
        
      
    

  实际上,调用委托时,给委托实例提供圆括号与调用委托的Invoke()方法,是完全相同的:

      
        1
      
       Console.WriteLine(stringMethod());  
      
        //
      
      
        委托方式1(使用圆括号的方式).
      
      
        2
      
       Console.WriteLine(stringMethod.Invoke());   
      
        //
      
      
        委托方式2(使用调用Invoke()方法的方式).
      
    

  原因是对于委托变量stringMethod,C#编译器会调用stringMethod.Invoke()代替stringMethod().

  值得注意的是,在给一个委托类型的变量赋值的时候,方法的名称不能带有"()"括号,上述例子,调用 x.ToString()方法,会返回一个不能赋予委托变量的字符串对象(而不是方法的地址).

  委托的一个特征是,它们是类型安全的,可以确定被调用的方法的签名是正确的.但是委托不关心在什么类型上调用改方法,甚至不考虑方法是静态的,还是实例方法.

  如下例子演示了委托可以使用实例方法,也可以使用静态方法:

  Currency结构的声明:

      
         1
      
      
        namespace
      
      
         Wrox.ProCSharp.Delegates {


      
      
         2
      
      
        struct
      
      
         Currency {


      
      
         3
      
      
        public
      
      
        uint
      
      
         Dollars;


      
      
         4
      
      
        public
      
      
        ushort
      
      
         Cents;


      
      
         5
      
      
         6
      
      
        public
      
       Currency(
      
        uint
      
       dollars, 
      
        ushort
      
      
         cents) {


      
      
         7
      
      
        this
      
      .Dollars =
      
         dollars;


      
      
         8
      
      
        this
      
      .Cents =
      
         cents;


      
      
         9
      
      
                }


      
      
        10
      
      
        11
      
      
        public
      
      
        override
      
      
        string
      
      
         ToString() {


      
      
        12
      
      
        return
      
      
        string
      
      .Format(
      
        "
      
      
        ${0}.{1,-2:00}
      
      
        "
      
      
        , Dollars, Cents);


      
      
        13
      
      
                }


      
      
        14
      
      
        15
      
      
        public
      
      
        static
      
      
        string
      
      
         GetCurrencyUnit() {


      
      
        16
      
      
        return
      
      
        "
      
      
        Dollar
      
      
        "
      
      
        ;


      
      
        17
      
      
                }


      
      
        18
      
      
        19
      
      
        public
      
      
        static
      
      
        explicit
      
      
        operator
      
       Currency(
      
        float
      
      
         value) {


      
      
        20
      
      
        checked
      
      
         {


      
      
        21
      
      
        uint
      
       dollars = (
      
        uint
      
      
        )value;


      
      
        22
      
      
        ushort
      
       cents = (
      
        ushort
      
      )((value - dollars) * 
      
        100
      
      
        );


      
      
        23
      
      
        return
      
      
        new
      
      
         Currency(dollars, cents);


      
      
        24
      
      
                    }


      
      
        25
      
      
                }


      
      
        26
      
      
        27
      
      
        public
      
      
        static
      
      
        implicit
      
      
        operator
      
      
        float
      
      
        (Currency value) {


      
      
        28
      
      
        return
      
       value.Dollars + (value.Cents / 
      
        100.0f
      
      
        );


      
      
        29
      
      
                }


      
      
        30
      
      
        31
      
      
        public
      
      
        static
      
      
        implicit
      
      
        operator
      
       Currency(
      
        uint
      
      
         value) {


      
      
        32
      
      
        return
      
      
        new
      
       Currency(value, 
      
        0
      
      
        );


      
      
        33
      
      
                }


      
      
        34
      
      
        35
      
      
        public
      
      
        static
      
      
        implicit
      
      
        operator
      
      
        uint
      
      
        (Currency value) {


      
      
        36
      
      
        return
      
      
         value.Dollars;


      
      
        37
      
      
                }


      
      
        38
      
      
            }


      
      
        39
      
      
        40
      
       }
    

在住函数中调用:

      
         1
      
      
        using
      
      
         System;


      
      
         2
      
      
         3
      
      
        namespace
      
      
         Wrox.ProCSharp.Delegates


      
      
         4
      
      
        {


      
      
         5
      
      
        class
      
      
         Program


      
      
         6
      
      
            {


      
      
         7
      
      
        private
      
      
        delegate
      
      
        string
      
      
         GetAString();


      
      
         8
      
      
         9
      
      
        static
      
      
        void
      
      
         Main()


      
      
        10
      
      
                {


      
      
        11
      
      
        int
      
       x = 
      
        40
      
      
        ;


      
      
        12
      
                   GetAString firstStringMethod =
      
         x.ToString;


      
      
        13
      
                   Console.WriteLine(
      
        "
      
      
        String is {0}
      
      
        "
      
      
        , firstStringMethod());


      
      
        14
      
      
        15
      
                   Currency balance = 
      
        new
      
       Currency(
      
        34
      
      , 
      
        50
      
      
        );


      
      
        16
      
      
        17
      
      
        //
      
      
         firstStringMethod references an instance method
      
      
        18
      
                   firstStringMethod =
      
         balance.ToString;


      
      
        19
      
                   Console.WriteLine(
      
        "
      
      
        String is {0}
      
      
        "
      
      
        , firstStringMethod());


      
      
        20
      
      
        21
      
      
        //
      
      
         firstStringMethod references a static method
      
      
        22
      
                   firstStringMethod = 
      
        new
      
      
         GetAString(Currency.GetCurrencyUnit);


      
      
        23
      
                   Console.WriteLine(
      
        "
      
      
        String is {0}
      
      
        "
      
      
        , firstStringMethod());


      
      
        24
      
      
        25
      
      
                }


      
      
        26
      
      
            }


      
      
        27
      
       }
    

   输出:

      String 
      
        is
      
      
        40
      
      
        

String 
      
      
        is
      
       $
      
        34.50
      
      
        

String 
      
      
        is
      
       Dollar
    

   再来看一个委托使用:

  定义操作的方法的类:

      
         1
      
      
        namespace
      
      
         SimpleDelegates_Demo {


      
      
         2
      
      
        class
      
      
         MathOperations {


      
      
         3
      
      
        public
      
      
        static
      
      
        double
      
       MultiplyByTwo(
      
        double
      
      
         value) {


      
      
         4
      
      
        return
      
       value * 
      
        2
      
      
        ;


      
      
         5
      
      
                }


      
      
         6
      
      
         7
      
      
        public
      
      
        static
      
      
        double
      
       Square(
      
        double
      
      
         value) {


      
      
         8
      
      
        return
      
       value *
      
         value;


      
      
         9
      
      
                }


      
      
        10
      
      
            }


      
      
        11
      
      
        12
      
       }
    

  在主函数中使用:

      
         1
      
      
        using
      
      
         System;


      
      
         2
      
      
         3
      
      
        namespace
      
      
         SimpleDelegates_Demo {


      
      
         4
      
      
        delegate
      
      
        double
      
       Operate(
      
        double
      
      
         input);


      
      
         5
      
      
        class
      
      
         Program {


      
      
         6
      
      
        static
      
      
        void
      
       Main(
      
        string
      
      
        [] args) {


      
      
         7
      
                   Operate[] actions =
      
         { MathOperations.MultiplyByTwo, MathOperations.Square };


      
      
         8
      
      
        //
      
      
        遍历每个委托实例.
      
      
         9
      
      
        foreach
      
       (Operate action 
      
        in
      
      
         actions) {


      
      
        10
      
                       ProcessAndDisplayResult(action, 
      
        2
      
      
        );


      
      
        11
      
                       ProcessAndDisplayResult(action, 
      
        2.5
      
      
        );


      
      
        12
      
                       ProcessAndDisplayResult(action, 
      
        5.2
      
      
        );                


      
      
        13
      
      
                        Console.WriteLine();


      
      
        14
      
      
                    }


      
      
        15
      
      
                }


      
      
        16
      
      
        17
      
      
        static
      
      
        void
      
       ProcessAndDisplayResult(Operate action, 
      
        double
      
      
         inputVal) {


      
      
        18
      
                   Console.WriteLine(
      
        "
      
      
        Input is [{0}],Result is [{1}]
      
      
        "
      
      
        , inputVal, action(inputVal));


      
      
        19
      
      
                }


      
      
        20
      
      
            }


      
      
        21
      
       }
    

  output:

      
        1
      
       Input 
      
        is
      
       [
      
        2
      
      ],Result 
      
        is
      
       [
      
        4
      
      
        ]


      
      
        2
      
       Input 
      
        is
      
       [
      
        2.5
      
      ],Result 
      
        is
      
       [
      
        5
      
      
        ]


      
      
        3
      
       Input 
      
        is
      
       [
      
        5.2
      
      ],Result 
      
        is
      
       [
      
        10.4
      
      
        ]


      
      
        4
      
      
        5
      
       Input 
      
        is
      
       [
      
        2
      
      ],Result 
      
        is
      
       [
      
        4
      
      
        ]


      
      
        6
      
       Input 
      
        is
      
       [
      
        2.5
      
      ],Result 
      
        is
      
       [
      
        6.25
      
      
        ]


      
      
        7
      
       Input 
      
        is
      
       [
      
        5.2
      
      ],Result 
      
        is
      
       [
      
        27.04
      
      ]
    

  在这个例子中,我们将委托实例封装到一个数组中,然后遍历每个委托实例,然后传递遍历到特定的方法中调用,这说明使用委托的一种方式 - 即把方法组合到一个数组中来使用,这样就可以在循环中调用不同的方法了.

  值得注意的是,这里 ProcessAndDisplayResult(Operate action, double inputVal) 不是多余的.

  当我们在主函数的第10~12行中传递action委托实例到 ProcessAndDisplayResult(Operate action, double inputVal) 方法的时候, action就是 委托表示的方法.

  而在ProcessAndDisplayResult(Operate action, double inputVal)方法体中,也就是上面Program类中的第18行中的action(inputVal),或action(2)实际上调用这个方法,参数放在圆括号中.也就是说, action(inputVal),或action(2) 实际上是调用action委托实例封装的方法.

委托的使用 - 浅谈


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论