C#入门(3)

Delegates, Events, Lambda Expressions

最早的windows是使用c风格的函数指针来进行callback的,但是这样仅仅传递了一个内存中的地址,无法包含更多的信息,如类型安全等,而且容易引发crash.

所以.Net平台下的delegate可以指向静态方法或者是对象方法,一般包含三种重要信息:

  1. 需要调用的方法的地址
  2. 方法的参数
  3. 方法的返回值

代理可以支持同步方法和异步方法:

对于一个delegate,首先编译器会生成一个seal的类.具体如下:

public delegate string MyDelegate(bool a, bool b, bool c);

sealed class MyDelegate : System.MulticastDelegate
{
public string Invoke(bool a, bool b, bool c);
public IAsyncResult BeginInvoke(bool a, bool b, bool c,AsyncCallback cb, object state);
public string EndInvoke(IAsyncResult result);
} // This is only pseudo-code!
public sealed class DelegateName : System.MulticastDelegate
{
public delegateReturnValue Invoke(allDelegateInputRefAndOutParams);
public IAsyncResult BeginInvoke(allDelegateInputRefAndOutParams,AsyncCallback cb, object state);
public delegateReturnValue EndInvoke(allDelegateRefAndOutParams,IAsyncResult result);
}

在生成的类中的三个方法中,Invoke()是负责同步(synchronized)的,该方法在使用正确的语法时,不需要显式调用.而剩下的两个BeginInvoke()和EndInvoke()是负责异步的(asynchronized),注意这里的BeginInvoke()后面会自动增加两个参数,一个是AsyncCallback,一个是object;而EndInvoke()的返回值则是delegate的返回值,参数则是BeginInvoke()的返回值.但是当使用out或者ref修饰的参数时,这样的参数也会传递给EndInvoke().

所以使用delegate声明,其实是继承了System.MulticastDelegate类和System.Delegate类.但是在程序中不能够显式继承自这两个类.下面给出了这两个类的部分:

public abstract class MulticastDelegate : Delegate
{
// Returns the list of methods "pointed to." public sealed override Delegate[] GetInvocationList();
// Overloaded operators.
public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2);
public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2); // Used internally to manage the list of methods maintained by the delegate.
private IntPtr _invocationCount;
private object _invocationList;
} public abstract class Delegate : ICloneable, ISerializable
{
// Methods to interact with the list of functions.
public static Delegate Combine(params Delegate[] delegates);
public static Delegate Combine(Delegate a, Delegate b);
public static Delegate Remove(Delegate source, Delegate value);
public static Delegate RemoveAll(Delegate source, Delegate value);
// Overloaded operators.
public static bool operator ==(Delegate d1, Delegate d2);
public static bool operator !=(Delegate d1, Delegate d2); // Properties that expose the delegate target.
public MethodInfo Method { get; }
public object Target { get; }
}

下表给出具体属性的含义:

Member Meaning
Method This property returns a System.Reflection.MethodInfo object that represents details of a static method maintained by the delegate.
Target If the method to be called is defined at the object level (rather than a static method), Target returns an object that represents the method maintained by the delegate. If the value returned from Target equals null, the method to be called is a static member.
Combine() This static method adds a method to the list maintained by the delegate. In C#, you trigger this method using the overloaded += operator as a shorthand notation.
GetInvocationList() This method returns an array of System.Delegate objects, each representing a particular method that may be invoked.
Remove() RemoveAll() These static methods remove a method (or all methods) from the delegate’s invocation list. In C#, the Remove() method can be called indirectly using the overloaded -= operator.

Combine()是当给delegate增加回调函数时用的,调用+=会隐式调用Combine(),

使用delegates:

一般使用delegates的步骤为:

  1. 定义一种新的delegates类型,来支持回调
  2. 在使用delegates的类中定义一个该delegates的成员变量,可以是private也可以是public
  3. 定义一个辅助函数来使得调用者可以方便的调用回调
  4. 实现函数,在其中正确地调用delegates变量

Tips:

在c#中的界面开发中,由于父级控件的属性设置对于子级控件是有影响的,因此对于多级嵌套的层级控件,必须定义好add的顺序,先将后继控件加载然后加入到前级控件和先加载自身,然后加载后继控件是不同的。A-1-B-2-C和A-2-B-1-C,如这个表达式,ABC依次为嵌套关系。数字代表加载顺序。

这里的关键因素是一个属性,一般是tabControl或者是tabPage有的,叫AutoScaleMode,默认的是根据Font来进行改变,因此当父级元素和子级元素中的Font设置不一样,甚至是设置的一样,但是加入时仍然会按照字体的大小进行缩放处理.所以将该属性设为none可以避免不必要的麻烦.

这个Tips如果算是Bug,应该解了.

C#入门(3)的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  3. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  4. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  5. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  6. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  7. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  8. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

  9. wepack+sass+vue 入门教程(一)

    一.安装node.js node.js是基础,必须先安装.而且最新版的node.js,已经集成了npm. 下载地址 node安装,一路按默认即可. 二.全局安装webpack npm install ...

  10. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

随机推荐

  1. 1.1-1.4 sqoop概述及安装cdh版hadoop

    一.概述 Sqoop是一个在结构化数据和Hadoop之间进行批量数据迁移的工具,结构化数据可以是Mysql.Oracle等RDBMS. Sqoop底层用MapReduce程序实现抽取.转换.加载,Ma ...

  2. 1.6 Hive配置metastore

    一.配置 1.配置文件 #创建配置文件 [root@hadoop-senior ~]# cd /opt/modules/hive-0.13.1/conf/ [root@hadoop-senior co ...

  3. Flutter实战视频-移动电商-44.详细页_首屏自定义Widget编写

    44.详细页_首屏自定义Widget编写 把详细页的图片.标题.编号和价格形成一个单独的widget去引用 详情页的顶部单独封装个插件 在pages下面新建detials_page的文件件并在里面新建 ...

  4. 精通BitmapData

    一.构造方法: var bmd:BitmapData=new BitmapData(200,100,true,0xffff0000); 参数说明: 1.宽 2.高 3.是否使用32位填充位图(包括al ...

  5. vc编程中出现 fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"”?

    解决办法菜单--〉项目--〉设置,出现“项目设置”对话框,左边展开项目,在“源文件”中找到出错的文件,然后在右边选择“C/C++”属性 页,在Category下拉框中选择“Precompiled He ...

  6. DirectX实现球面纹理映射

    http://www.cnblogs.com/graphics/archive/2011/09/13/2174022.html DirectX实现球面纹理映射 介绍 球面纹理映射就是将一个平面纹理映射 ...

  7. [Xcode 实际操作]三、视图控制器-(1)使用UIScrollView展示多个视图可控制器

    目录:[Swift]Xcode实际操作 本文将演示使用滚动视图创建多个页面. [Create a new Xcode project]->[Single View App]->[Next] ...

  8. [Xcode 实际操作]九、实用进阶-(16)给图片添加水印效果

    目录:[Swift]Xcode实际操作 本文将演示如何截取屏幕画面,并将截取图片,存入系统相册. 在项目文件夹[DemoApp]上点击鼠标右键 ->[New File]创建一个扩展文件-> ...

  9. sed 删除指定行

    参考:http://blog.sina.com.cn/s/blog_4ba5b45e0102e7l2.html

  10. Windows 2008 R2 如何安装.net framework 3.5

    服务器中安装sql server2012 ,  安装过程中提示没有此 “ Framework 3.5.1 功能 ” , 是不是很尴尬 于是简单记录安装 Framework 3.5.1 功能的步骤 一. ...