起源

在C语言中,一个函数名代表的是一个地址。比如,创建一个函数int add(int x,int y),此时的函数名add等同于函数地址,调用方法:add(2,4)。这一点没有什么讨论的。

随着typeof的使用,可以使用一个函数指针,typeof int(*P)(int,int),它表示一个函数指针类型,该指针指向两个形参,返回值为int的函数形式。此时P为一个类型,调用它等价于add

比如P p=&add;

p(20,30),相当于等价调用add

——————————————————

看到上面的例子,直觉的想到,能不能把这个函数指针类型放到形参中,这样就可以执行不同的操作。比如:

int Calc(P p,int x,int y){

  p(x,y);

}

此时的P是很空泛的概念,只要符合函数指针类型的函数都可以进来,比如加减乘除等各种方法都可以适配,也就是说,用一个方法Calc可以执行各种运算,在这里p可以看作一个方法。在这里,我们看明白了,这些转化的操作就是想把方法放到形参中

如果我们熟练JS(也可以说是函数式编程语言),JS中函数是一等公民,把函数作为形参是非常平常的事情。(注:关于委托,还会在C++相关笔记中进行记录)

为了记忆方便,提取了重点。

委托类似于指针,可以理解为函数指针的升级版,这是理解委托最关键的地方。

Action和Func

系统自带的两种委托:

  • Action
  • Func

Action型委托要求委托的目标方法没有返回值,但是可以有形参

Action  action=new Action(目标方法);

Func型委托要求委托的目标方法可以带有返回值和形参,形如:

Func<T1,T2,T3> func1=new Func<T1,T2,T3>(目标方法);

* 其中,T1为返回类型,T2、T3表示形参类型

自定义委托delegate的声明

  • 委托是一种类(class),类是数据类型所以委托也是一种数据类型
  • 它的声名方式与一般的类不同,主要是为了照顾可读性和C/C++传统
  • 注意声明委托的位置,避免写错地方结果声明成嵌套类型
  • delegate   double   Calc    (double x,double y);

可以与C语言函数指针类比:typedef void(*p)(int,int);

委托的一般使用

实例:把方法当作参数传给另一个方法

  • 正确使用:模板方法,“借用”指定的外部方法来产生结果
  • 正确使用2:回调方法(callback),调用指定的外部方法

模板方法

结论:

模板方法的作用在于复用。

完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DelegateExample
{
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory(); Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);
Box box1 = wrapFactory.WrapProduct(func1);
Box box2 = wrapFactory.WrapProduct(func2); Console.WriteLine(box1.Product.Name); }
class Product //产品类
{
public string Name { get; set; }
}
class Box //盒子类
{
public Product Product { get; set; }
}
class WrapFactory //包装工厂
{
public Box WrapProduct(Func<Product> getProduct)
{
Box box = new Box();
Product product = getProduct.Invoke();
box.Product = product;
return box;
}
}
class ProductFactory //产品工厂
{
public Product MakePizza()
{
Product product = new Product();
product.Name = "Pizza";
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "ToyCar";
return product;
}
}
}
}

回调方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DelegateExample
{
class Program
{
static void Main(string[] args)
{
ProductFactory productFactory = new ProductFactory();
WrapFactory wrapFactory = new WrapFactory(); Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar); Logger logger = new Logger();
Action<Product> log = new Action<Product>(logger.Log); //Log的委托; Box box1 = wrapFactory.WrapProduct(func1, log);
Box box2 = wrapFactory.WrapProduct(func2, log); Console.WriteLine(box1.Product.Name); }
class Product //产品类
{
public string Name { get; set; }
public double Price { get; set; }
}
class Box //盒子类
{
public Product Product { get; set; }
}
class Logger
{
public void Log(Product product)
{
Console.WriteLine(product.Price);
}
}
class WrapFactory //包装工厂
{
public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback)
{
Box box = new Box();
Product product = getProduct.Invoke();
if (product.Price > ) //如果产品价格大于50,就执行回调方法;
{
logCallback(product);
}
box.Product = product;
return box;
}
}
class ProductFactory //产品工厂
{
public Product MakePizza()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = ;
return product;
}
public Product MakeToyCar()
{
Product product = new Product();
product.Name = "ToyCar";
product.Price = ;
return product;
}
}
}
}

C#重点内容之:委托(delegate)的更多相关文章

  1. [C#] C# 知识回顾 - 委托 delegate

    C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...

  2. C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数

    C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...

  3. IOS开发使用委托delegate在不同窗口之间传递数据

    IOS开发使用委托delegate在不同窗口之间传递数据是本文要介绍的内容,主要是来讲解如何使用委托delegate在不同窗口之间传递数据,具体内容来看详细内容.在IOS开发里两个UIView窗口之间 ...

  4. [.NET] C# 知识回顾 - 委托 delegate (续)

    C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...

  5. C# 委托Delegate(一) 基础介绍&用法

    本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...

  6. 为什么不能把委托(delegate)放在一个接口(interface)当中?

    stackoverflow上有人问,为什么不能把委托放在一个接口当中? 投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't g ...

  7. C# 代理/委托 Delegate

    本文转载自努力,努力,努力 1. 委托的定义:委托是函数的封装,它代表一"类"函数.他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数 ...

  8. c# 委托 delegate

    委托是一种存储函数引用的类型,在事件和事件的处理时有重要的用途 通俗的说,委托是一个可以引用方法的类型,当创建一个委托,也就创建一个引用方法的变量,进而就可以调用那个方法,即委托可以调用它所指的方法. ...

  9. 理解委托(delegate)及为什么要使用委托

    理解委托(delegate)及为什么要使用委托 委托:是一种定义方法签名的类型. 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联. 您可以通过委托实例调用方法. 上述为官方说法,理解起来 ...

随机推荐

  1. python:在for遍历list时使用remove出现的问题以及解析(转)

    原文地址:http://blog.csdn.net/circle2015/article/details/64444300最近面试时,面试官在纸上写了几行代码,说是很简单的问题,我看后直接懵逼...如 ...

  2. maven工程的拆分与聚合

    1.创建父工程: 首先创建maven Project: 点击next,进入下一个页面,勾选上create a simple project: 点击next,进入下一页面,在这里与创建普通maven工程 ...

  3. mysql命令行导入结构化数据

    数据样本 103252765-|--|-stephanie_mt@hotmail.com-|-o/35+nGaNEU=-|-ion|-- 其中|为分隔符,每行的换行符\n mysql -uroot M ...

  4. windbg 加载dump监测蓝屏原因时出现重复的星星框提示解决办法

    加载dump文件出现了重复上边的信息 总结: 要reload一下环境,说明符号库未加载出现的错误,!sym noisy 显示详细信息 ,reload重载符号库,未找到的,从服务器进行下载, 注意,第一 ...

  5. if语句中的 == 和= 区别

    ”==“ 是判断二者的值是否相等   ”=“是赋值,是将后者的值赋值给前者,不需要比较,在if语句中用”==“来判断ul当前的状态,来判断执行的操作,若是用”=“,则相等于说ul的状态就是后者,直接执 ...

  6. list集合与HashMap的使用

    List<Map<String, Object>> arrays= new ArrayList<Map<String, Object>>(); Hash ...

  7. PAT 1088 三人行(20 分)(暴力破解+流程分析)

    1088 三人行(20 分) 子曰:"三人行,必有我师焉.择其善者而从之,其不善者而改之." 本题给定甲.乙.丙三个人的能力值关系为:甲的能力值确定是 2 位正整数:把甲的能力值的 ...

  8. epoll机制:epoll_create、epoll_ctl、epoll_wait、close

      在Linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll.相比于select,epoll最大的好处在于它不会随着监听fd数 ...

  9. UI设计教程:关于版式设计

    版式设计是视觉传达的重要手段之一,版式设计,即把有限的视觉元素在版面页进行有效的视觉组合,最优化地传达信息的同时,去影响受众,使受众产生视觉上的美感. 版式设计基本流程  在进行版式设计时,设计作品的 ...

  10. HTML5中的Web Notification桌面通知(右下角提示)

    html5桌面通知(Web Notifications)对于需要实现在新消息入线时,有桌面通知效果的情况下非常有用,在此简单介绍一下这个html5的新属性.通过Web Notifications(桌面 ...