定义委托的语法如下
delegata void IntMethodInvoker(int x);
定义了委托 IntMethodInvoker,并指定该委托的每个实例都可以包含一个方法的使用,该方法带有一个int 参数,并返回void。理解委托的一种好方式是把委托当作这样一件事情,它给方法的签名和返回类型指定名称。
private delegate string GetAString();
static void Main(string[] args)
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);
//GetAString firstStringMethod = x.ToString;
Console.WriteLine("string is {0}", firstStringMethod());
Console.ReadKey();
}
实例化了类型为GetAString的一个委托,并对它初始化,使它引用整型变量 x的ToString()方法(指定实例和方法名来初始话委托)。
简单的委托示例
class MathOperations
{
public static double MultiplyByTwo(double value)
{
return value * 2;
}
public static double Square(double value)
{
return value * value;
}
}
class Program
{
delegate double DoubleOp(double x);
static void Main(string[] args)
{
DoubleOp[] operations = { MathOperations.MultiplyByTwo,
MathOperations.Square};
for(int i=0;i<operations.Length;i++)
{
Console.WriteLine("using operations[{0}]:", i);
ProcessAndDisplayNumber(operations[i], 2.0);
ProcessAndDisplayNumber(operations[i], 7.94);
ProcessAndDisplayNumber(operations[i], 1.414);
Console.WriteLine();
}
Console.ReadKey();
}
private static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
double result = action(value);
Console.WriteLine("value is {0},result of operations is {1}", value, result);
}
}
Action<T>和Fun<T>委托
Act<T>委托表示引用一个void返回类型的方法。Fun<T>委托允许调用返回类型的方法。
实例
class BubbleSorter
{
static public void Sort<T>(IList<T>sortArray,Func<T,T,bool>comparison)
{
bool swapped = true;
do
{
swapped = false;
for (int i = 0; i < sortArray.Count - 1; i++)
{
if (comparison(sortArray[i + 1], sortArray[i]))
{
T temp = sortArray[i];
sortArray[i] = sortArray[i + 1];
sortArray[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
}
}
class Employee
{
public string Name { get; private set; }
public decimal Salary { get; private set; }
public Employee(string name,decimal salary)
{
this.Name = name;
this.Salary = salary;
}
public override string ToString()
{
return string.Format("{0},{1:C}", Name, Salary);
}
//为了匹配Func<T,T,bool>委托的签名,必须定义CompareSalary,它的参数是两个Employee引
//用,并返回一个布尔值。
public static bool CompareSalary(Employee e1,Employee e2)
{
return e1.Salary < e2.Salary;
}
}
class Program
{
static void Main(string[] args)
{
Employee[] employees =
{
new Employee("Bugs",20000),
new Employee("Elmer",10000),
new Employee("Daffy",25000),
new Employee("Wile",100000),
new Employee("Foghorn",23000),
new Employee("Road",50000)
};
BubbleSorter.Sort(employees, Employee.CompareSalary);
foreach(var employee in employees)
{
Console.WriteLine(employee);
}
Console.ReadKey();
}
}
多播委托
通过一个委托调用多个方法可能导致一个大问题,多播委托包含一个逐个调用的委托集合。如果通过委托调用的其中一个方法抛出一个异常,整个迭代就会停止
class Program
{
static void One()
{
Console.WriteLine("one");
throw new Exception("error in one");
}
static void Two()
{
Console.WriteLine("two");
}
static void Main(string[] args)
{
Action d1 = One;
d1 += Two;
Delegate[] delegates = d1.GetInvocationList();
foreach (Action d in delegates)
{
try
{
d();
}
catch
{
Console.WriteLine("Exception caught");
}
}
Console.ReadKey();
}
}
注意
在使用匿名方法时不能使用 跳转语句跳转匿名方法外部,反之亦然。