委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示:

public delegate int PerformCalculation(int x, int y);

与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。这样就可以通过编程方式来更改方法调用,还可以向现有类中插入新代码。只要知道委托的签名,便可以分配自己的委托方法。

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,可以向排序算法传递对比较两个对象的方法的引用。分离比较代码使得可以采用更通用的方式编写算法。

委托具有以下特点:

委托类似于 C++ 函数指针,但它是类型安全的。

委托允许将方法作为参数进行传递。

委托可用于定义回调方法。

委托可以链接在一起;例如,可以对一个事件调用多个方法。

方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。

C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。

 

委托和接口都允许类设计器分离类型声明和实现。给定的接口可由任何类或结构继承和实现;可以为任何类中的方法创建委托,前提是该方法符合委托的方法签名。接口引用或委托可由不了解实现该接口或委托方法的类的对象使用。既然存在这些相似性,那么类设计器何时应使用委托,何时又该使用接口呢?

在以下情况中使用委托:

当使用事件设计模式时。

当封装静态方法可取时。

当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。

需要方便的组合。

当类可能需要该方法的多个实现时。

在以下情况中使用接口:

当存在一组可能被调用的相关方法时。

当类只需要方法的单个实现时。

当使用接口的类想要将该接口强制转换为其他接口或类类型时。

当正在实现的方法链接到类的类型或标识时:例如比较方法。

使用单一方法接口而不使用委托的一个很好的示例是 IComparable 或 IComparable。IComparable 声明 CompareTo 方法,该方法返回一个整数,以指定相同类型的两个对象之间的小于、等于或大于关系。IComparable 可用作排序算法的基础,虽然将委托比较方法用作排序算法的基础是有效的,但是并不理想。因为进行比较的能力属于类,而比较算法不会在运行时改变,所以单一方法接口是理想的。



委托例子
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    delegate double DoubleOp(double x);

    class Program
    {

        public static void Process(DoubleOp action, double value)
        {
            double result = action(value);
            Console.WriteLine("value is {0} ,result is {1}",value,result);
        }
        static void Main(string[] args)
        {
            DoubleOp[] operations =
            {
                new DoubleOp(MathsOperations.MultiplyByTwo),
                new DoubleOp(MathsOperations.Square)
            };
            for (int i = 0; i < operations.Length;i++ )
            {
                Console.WriteLine("Using operations[{0}]",i);
                Process(operations[i],2.0);
                Process(operations[i],7.94);
                Console.WriteLine("=========================");
            }
        } 
   
    }
    class MathsOperations
    {
        public static double MultiplyByTwo(double value)
        {
            return value * 2;
        }
        public static double Square(double value)
        {
            return value * value;
        }
    }
}
====================================
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    delegate bool CompareOp(object lhs,object rhs);
    class Program
    {
        static void Main(string[] args)
        {
            Employee[] employees =
            {
              new Employee("Bugs",20000),
              new Employee("AAA",10000),
              new Employee("xccx",25000)
            };
            CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsCreater);
            BubbleSorter.Sort(employees,employeeCompareOp);
            for (int i = 0; i < employees.Length;i++)
            {
                Console.WriteLine(employees[i].ToString());
            }
        }
    }
    class BubbleSorter
    {
        public static void Sort(object[] sortArray,CompareOp gtMethod)
        {
            for (int i = 0; i < sortArray.Length;i++)
            {
                for (int j = i + 1; j < sortArray.Length;j++ )
                {
                    if(gtMethod(sortArray[j],sortArray[i]))
                    {
                        object temp=sortArray[i];
                        sortArray[i]=sortArray[j];
                        sortArray[j] = temp;
                    }
                }
            }
        }
    }
    class Employee
    {
        private string name;
        private decimal salary;

        public Employee(string name,decimal salary)
        {
            this.name = name;
            this.salary = salary;
        }
        public override string ToString()
        {
            return string.Format(name+",{0:C}",salary);
        }
        public static bool RhsIsCreater(object lhs,object rhs)
        {
            Employee empLhs=(Employee)lhs;
            Employee empRhs=(Employee)rhs;
            return (empRhs.salary > empLhs.salary) ? true : false;
        }
    }

 
}

 

 转:http://www.cnblogs.com/blueskygenius/archive/2007/08/16/857782.html

posted on 2008-09-22 22:32  赛纳行星  阅读(314)  评论(0编辑  收藏  举报