委托很像C语言的函数指针,是函数指针的升级版。
先贴上一段C语言的函数指针。
#includetypedef int(*Calcu)(int x,int y); int Add(int x,int y){ return x+y; } int Sub(int x,int y){ return x-y; } int aha(int m,int n,Calcu s){ return s(m,n); } int main(){ int m=100,n=10; Calcu x=Add; Calcu y=Sub; printf("%dn",(*x)(1,2)); //或:x(1,2)即可 int result1=aha(m,n,x); int result2=aha(m,n,y); printf("%d %d",result1,result2); return 0; }
函数指针记录了函数的地址,可以直接通过他来直接调用函数,或者作为参数传入其他函数。委托也有这种作用。
委托是函数指针的升级版,它可以通过某些限定条件,来指向某些目标方法,帮助我们完成对方法的间接调用。
委托是一个类,C#已经帮我们定义了很多种委托。其中,Action和Function是最常见的委托。
//Action委托,只接受返回值和参数都是空的方法
namespace ConsoleAppPractice
{
public delegate bool Compare(int x, int y);
class Program
{
static void Main()
{
Test test = new Test();
Action action = new Action(test.laugh);//此处只写函数名就行。
action();
action.Invoke();//两种调用方法
}
}
class Test
{
public void laugh()
{
Console.WriteLine("哈哈!");
}
}
}
//使用Func委托:Func是泛类型,尖括号中接受的参数,第一个是方法返回值,后面的是方法参数
namespace ConsoleAppPractice
{
public delegate bool Compare(int x, int y);
class Program
{
static void Main()
{
Test test = new Test();
Func func = new Func(test.Add);
int result = func(1, 2);
Console.WriteLine(result);
}
}
class Test
{
public int Add(int x,int y)
{
return x + y;
}
}
}
如果要自定义委托:
委托是类,是一种数据类型,故虽然C#支持类的嵌套,但是最好还是放在与其他类并列的名称空间体里。
委托的声明方式不同于其他的类,主要是为了照顾可读性和C的传统。
委托定义需与方法兼容。
下面的冒泡排序一例便给出了自定义委托类型,并且以模板方法方式使用的例子:
namespace ConsoleAppPractice
{
public delegate bool Compare(int x, int y);
class Program
{
static void Main()
{
int[] array = new int[] { 1, 2, 6, 4, 2, 8, 3, 9 };
string str = Console.ReadLine();
int choice = int.Parse(str);
Compare compare1 = new Compare(Comparasion.compare1);
Compare compare2 = new Compare(Comparasion.compare2);
switch (choice)
{
case 1:
BubbleSort.BubbleSorting(array, array.Length, compare1);
break;
default:
BubbleSort.BubbleSorting(array, array.Length, compare2);
break;
}
foreach (var item in array)
{
Console.WriteLine(item);
}
}
}
class Comparasion
{
public static bool compare1(int x,int y)
{
return x > y;
}
public static bool compare2(int x,int y)
{
return x < y;
}
}
class BubbleSort
{
private bool isWEN = true;
public bool IsWEN
{
get { return isWEN = true;; }
}
public static void BubbleSorting(int[]array,int length,Compare compare)
{
for (int i = length-1; i >= 0; i--)
{
for (int j = 0; j < i; j++)
{
if (compare(array[j+1], array[j]))
{
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
}
}
委托的使用方法:
委托一般用于把方法当作一个参数传给另一个函数。
正确使用1:“模板方法”,借用指定的外部方法来产生结果。
namespace ConsoleAppPractice
{
public delegate bool Compare(int x, int y);
class Program
{
static void Main()
{
Func createPizza = new Func(ProductFactory.CreatePizza);
Func createToy = new Func(ProductFactory.CreateToy);
Box boxPizza = new Box();
Box boxToy = new Box();
boxPizza = Wrap.WrapProduct(createPizza);
boxToy = Wrap.WrapProduct(createToy);
Console.WriteLine(boxPizza.product.Name);
Console.WriteLine(boxToy.product.Name);
}
}
class Product
{
public string Name { get; set; }
}
class Box
{
public Product product { get; set; }
}
class ProductFactory
{
public static Product CreatePizza()
{
Product product = new Product();
product.Name = "Pizza";
return product;
}
public static Product CreateToy()
{
Product product = new Product();
product.Name = "Toy";
return product;
}
}
class Wrap
{
public static Box WrapProduct(Func create)
{
Box box = new Box();
box.product = create();
return box;
}
}
}
在wrap函数中,就是依照传入的create方法的不同,来创造出不同的产品。当产品数增多时,依然只需要这一个方法。因而可以减少代码长度,提高可读性。
正确使用2:“回调方法”,需要你时才调用
namespace ConsoleAppPractice
{
public delegate bool Compare(int x, int y);
class Program
{
static void Main()
{
Func createPizza = new Func(ProductFactory.CreatePizza);
Func createToy = new Func(ProductFactory.CreateToy);
Action log = new Action(Log.CreateLog);
Box boxPizza = Wrap.WrapProduct(createPizza,log);
Box boxToy = Wrap.WrapProduct(createToy,log);
Console.WriteLine(boxPizza.product.Name);
Console.WriteLine(boxToy.product.Name);
}
}
class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
class Box
{
public Product product { get; set; }
}
class ProductFactory
{
public static Product CreatePizza()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 3;
return product;
}
public static Product CreateToy()
{
Product product = new Product();
product.Name = "Toy";
product.Price = 900;
return product;
}
}
class Wrap
{
public static Box WrapProduct(Func create,Action log)
{
Box box = new Box();
box.product = create();
if (box.product.Price > 50)
{
Console.WriteLine("The product is {0}.",box.product.Name);
log();
}
return box;
}
}
class Log
{
public static void CreateLog()
{
Console.WriteLine("Wrap-day is {0}",DateTime.Now);
}
}
}



