标签(空格分隔): C#


看Markdown效果支持的不大好。

买来《CLR Via C#》这本书很久了,一直也没有对其进行总结,看的非常凌乱,趁此机会好好总结一下,也算对C#学习的一个总结。

  • 初识委托
  • 用委托回调方法
  • 泛型委托
  • 简化语法

初识委托

委托类型 (delegate type) 表示对具有特定参数列表和返回类型的方法的引用(个人觉得这句话对委托的解释非常好)。通过委托,我们能够将方法作为实体赋值给变量和作为参数传递。委托类似于在其他某些语言中的函数指针的概念。.NET Framework通过委托来提供回调函数机制,委托确保了回调函数是类型安全的。

调用一个委托的方法:

  1. 声明一个委托类型
  2. 声明一个方法包含要执行的代码
  3. 创建一个委托实例
  4. 调用这个委托实例

用委托回调方法

//1、声明一个委托实例
internal sealed class DelegateIntro {
internal delegate void Feedback(Int32 value);
private static void StaticDelegateDemo() {
Console.WriteLine("----- Static Delegate Demo -----");
//传递的为NUll,处理每个数据项都不调用回调方法
Counter(1, 3, null);
//3、创建静态的委托实例,用委托回调静态方法
Counter(1, 3, new Feedback(DelegateIntro.FeedbackToConsole));
Counter(1, 3, new Feedback(FeedbackToMsgBox)); // "Program." is optional
Console.WriteLine();
} private static void InstanceDelegateDemo() {
Console.WriteLine("----- Instance Delegate Demo -----");
//3、创建实例委托,用委托回调实例方法
DelegateIntro di = new DelegateIntro();
Counter(1, 3, new Feedback(di.FeedbackToFile)); Console.WriteLine();
} private static void Counter(Int32 from, Int32 to, Feedback fb) {
for (Int32 val = from; val <= to; val++) {
// If any callbacks are specified, call them
if (fb != null)
//4、调用这个委托
fb(val);
}
}
//2、声明一个方法包含要执行的代码
private static void FeedbackToConsole(Int32 value) {
Console.WriteLine("Item=" + value);
}
//2、声明一个方法包含要执行的代码
private static void FeedbackToMsgBox(Int32 value) {
MessageBox.Show("Item=" + value);
} private void FeedbackToFile(Int32 value) {
StreamWriter sw = new StreamWriter("Status", true);
sw.WriteLine("Item=" + value);
sw.Close();
}
}

委托对象是方法的包装器(wrapper),是方法能通过包装器来间接回调。如上的FeedbackToConsoleFeedbackToMsgBox方法通过委托包装,通过Counter方法来间接回调。

这个例子中的所有操作都是类型安全的。例如:在构造Feedback委托对象时,编译器确保FeedbackToConsoleFeedbackToMsgBox方法的签名兼容于Feedback委托类型定义的签名。具体的说,两个方法都要获取一个参数(一个int32),而且两者都熬有相同的返回类型(Void),将FeedbackToConsole的定义改为下面这样

private static Boolean FeedbackToCOnsole(string value){

···

}

C#编译器将不会编译以上代码,并报告一下错误:

error CS0123:"FeedbackToConsole"的重载均与委托"Feedback"不匹配

将方法绑定到委托时,C#和CLR都允许引用类型的协变性逆变性协变性是指方法能返回从委托的返回类型派生的一个类型。逆变性是指方法获取的参数可以是委托的参数类型的基类。

比如:

delegate object Mycallback(fileStream s);

完全可以构造该委托类型的一个实例并绑定到具有以下原型的方法

String SomeMethod(Stream s);

在这里,SomeMethod的返回类型String派生自委托的返回类型(Object),这是协变性;SomeMethod的参数类型Stream是委托的参数类型FileStream的基类,这是逆变性

注意只有引用类型才支持协变性和逆变性。

泛型委托

.NET Framework现在支持泛型,如返回void可用下面泛型

public delegate void Action();

public delegate void Action(T obj);

public delegate void Action<T1,T2>(T1 arg1,T2 arg2);

public delegate void Action<T1,T2,T3>(T1 arg1,T2 arg2,T3 arg3);

...

事实上,.NET Framework现在提供了17个Action委托,它们从无参数到最多16个参数,使用起来非常方便。如果需要返回值,可使用Func函数。如果需要使用ref或out关键字以传引用的方式传递参数,就需要自己定义委托了。

简化语法

简化语法1:不要构造委托对象。

如:

ThreadPool.QueueUserWorkItem(SomeAsyncTask,5);

本来ThreadPool类的静态QueueUserWorkItem方法期待一个WaitCallback委托对象的引用,但你现在直接可以传递一个方法符合waitCallback类型就可以了。但C#编译器其实还是会生成waitcallback委托对象--只是语法简化了而已。

简化语法2:不需要定义回调方法(lambda表达式)

前面代码中,回调方法名称SomeAsyncTask传给ThreadPool的QueueUserWorkItem方法。如果方法较为简单可以直接写为:

ThreadPool.QueueUserWorkItem(obj=>Console.WriteLine(Obj),5);

编译器在看到则个lambda表达式后会生成一个匿名方法。新的语言规范建议开发人员多多使用lambda表达式语法。

书本中的用委托回调多个方法没有总结,个人觉得现在一个方法已经差不多了,等理解的好了再去研究调用多个方法。

文章另外地址:https://www.zybuluo.com/kuier1992/note/163707

C#委托学习的更多相关文章

  1. 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

    引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...

  2. 委托学习总结(一)浅谈对C#委托理解

    初入社会,对于我这个初级程序员来说要学的东西实在太多了,公司最近在做一个winform框架开发的桌面应用程序,众所周知,winform也好,webform也好,里面随处可见的事件驱动,有事件,当然也少 ...

  3. 委托学习总结(二)匿名方法和lambda表达式

    之前总结了委托这个困惑着大多初学者的概念,继续来学习匿名方法和lambda表达式 (1)我们之前写了这样一段代码 //自定义一个委托 public delegate int Expression(in ...

  4. 《C#高级编程》之委托学习笔记 (转载)

    全文摘自 http://www.cnblogs.com/xun126/archive/2010/12/30/1921551.html 写得不错,特意备份!并改正其中的错误代码..     正文: 最近 ...

  5. C# 委托学习笔记

    接触委托 代理 delegate很久啦.除了看API,Kotoba也给我讲了 .说到委托,拿下面这个小例子比较好.(14年6月26花花给我的练习) 实例:写一个方法A,定义个方法B(打印hello), ...

  6. JS事件委托学习(转)

    JS 事件委托就是利用冒泡原理,把事件加到父级上触发,执行效果. 好处: 1.提高性能 2.新添加的元素还会有之前的事件     <</</</</li></ ...

  7. 委托学习续:Action、Func和Predicate

    我们先看一个上一章的委托的例子: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  8. C# 异步和委托学习

    IAsyncResult是接口: IAsyncResult 异步设计模式通过名为 BeginOperationName 和 EndOperationName 的两个方法来实现原同步方法的异步调用,如 ...

  9. 【C#】C#委托学习

    虽然做.NET这行也快2年了,但基础不太好啊,今天看了下委托方面的知识,记录下. 1.委托 总的来说,委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋 ...

随机推荐

  1. How to DEBUG a trigger or procedure

    DEBUGGING STORED PROCEDURES Over the past several weeks, we’ve been working on debugging a stored pr ...

  2. springmvc中RequestMapping的解析

    在研究源码的时候,我们应该从最高层来看,所以我们先看这个接口的定义: package org.springframework.web.servlet; import javax.servlet.htt ...

  3. 第 13 章 CSS 选择器[上]

    学习要点: 1.选择器总汇 2.基本选择器 3.复合选择器 4.伪元素选择器 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 选择器,通过选择器定位到想要设置样式的元素.目前 CSS 选择器的 ...

  4. 七个结构模式之外观模式(Facade Pattern)

    定义: 为子系统的一组接口提供一个统一的入口,从而降低系统之间的耦合度,提高子系统的可用性.外观模式又称为门面模式,是迪米特法则的一个体现,主要目的就是降低耦合. 结构图 Facade:抽象外观类,子 ...

  5. 设计模式之 面向对象的养猪厂的故事,C#演示(一)

    对于设计模式, 从本质上说, 其最大的用途就是适应需求的变化. 因为有了设计模式,我们可以在设计阶段就为未来可能发生的变化留下足够的空间. 我们通过一个建造现代化养猪场的故事, 来讨论一下设计模式与需 ...

  6. Guacamole之实现和架构(一)

    摘要 在网上看到一篇Guacamole官方手册的翻译,但是找不到后续,于是想自己也翻译几篇,有时间的话,会尽量多翻译一些.第一篇就直接转载过来了. Guacamole的介绍以及架构 Guacamole ...

  7. Sharepoint2013:日期控件报错

    1 问题 1> 在sharepoint中的,日期控件(DateTimeControl),日期过滤控件(Date Filter)和SPListViewFilter等包含日期组件的控件,在特定情况下 ...

  8. Framer – 将视觉搞转换为更真实的动态原型

    Framer 是一个 JavaScript 框架,简化了创建现实原型,实现完整的3D效果.以一种简单,可读的和强大的方式定义交互和创建动画. 另外还有 Framer Generator  是一个桌面应 ...

  9. JavaScript 事件入门

    一.事件介绍 JavaScript 有三种事件模型:内联模型.脚本模型和 DOM2 模型. 二.内联模型 //在 HTML 中把事件处理函数作为属性执行 JS 代码 <input type=&q ...

  10. CodeIgniter_2 路由中定义伪静态 直接映射到相关的控制器

    某些情况下 隐藏路径信息 使用伪静态定义: RewriteRule ^no/torrent(.*)$ /index.php/torrent/doit/$1 CodeIgniter会自动识别到 no 控 ...