做一个决定,并不难,难的是付诸行动,并且坚持到底 --Aaronyang的博客(www.ayjs.net)-www.8mi.me

1. 委托-我的总结

1.1 委托:面试我都会说,把方法当参数。委托包含的只是一个或多个方法的地址。

示例1:(一次执行多个同方法签名的方法)

/*
*2015年1月3日23:12:13 aaronyang
*网址:www.ayjs.net www.8mi.me
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace demo0103
{
delegate void TotalMethod(int type);//第一步delegate 方法签名 定义个方法的样子,如同接口
class Program
{
static void Main(string[] args)
{
//TotalMethod tm =new TotalMethod(Method1);//或者 非常建议 直接 +=或者=
TotalMethod tm = Method1 ;
tm += Method2;
tm += Method3;
tm();//一次性执行3个方法
tm.Invoke(3);//或者使用Invoke方法
Console.ReadLine();
} static void Method1(int t) {
Console.WriteLine("Method1:"+t*+"\t");
} static void Method2(int t)
{
Console.WriteLine("Method2:" + t * + "\t");
}
static void Method3(int t)
{
Console.WriteLine("Method3:" + t * + "\t");
} } }

效果:

示例2:委托类型的数组。把委托当做参数,这个技巧一定要掌握,可以写出很精彩的代码,很像Javascript传方法。方法的Lambda表达式写法初次见面

/*
*2015年1月3日23:12:13 aaronyang
*网址:www.ayjs.net www.8mi.me
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace demo0103
{
delegate void TotalMethod(ref int type);//第一步delegate 方法签名 定义个方法的样子,如同接口 /// <summary>
/// 处理TotalMethod方法,将转换后的数字,按照count数进行一定同样的数字相乘
/// 我没有定义一个和此委托方法签名一致的方法,使用的是Lambda表达式定义一个方法
/// </summary>
/// <param name="total"></param>
/// <param name="count"></param>
/// <returns></returns>
delegate int ProcessTotalMethod(TotalMethod total,int count); class Program
{
static void Main(string[] args)
{
//TotalMethod tm =new TotalMethod(Method1);//或者 非常建议 直接 +=或者=
//TotalMethod tm = Method1 ;
// tm += Method2;
// tm += Method3;
//tm(2);//一次性执行3个方法
//tm.Invoke(3);//或者使用Invoke方法 TotalMethod[] tms = { Method1, Method2, Method3 }; //委托数组
int initTypeNum=; ProcessTotalMethod ptm = (x,y) => {
x(ref initTypeNum);//将init按照10,100,1000倍相乘,并返回
Console.WriteLine("乘以倍数后的数字:" + initTypeNum );
//接下来连续乘以y个 initTypeNum
for (int i = ; i < y; i++)
{
initTypeNum *= initTypeNum;
}
return initTypeNum;
};
Console.WriteLine("终于连续2次相乘后的数字:" + ptm(tms[], )); Console.ReadLine();
} static void Method1(ref int t) {
t = t * ;
Console.WriteLine("Method1:"+t+"\t");
} static void Method2(ref int t)
{
t = t * ;
Console.WriteLine("Method2:" + t + "\t");
}
static void Method3(ref int t)
{
t = t * ;
Console.WriteLine("Method3:" + t + "\t");
} } }

效果:

1.2  框架自带好的常用的 Action<T1,[T2]...[T8]>和Func<T1,T2..[T8]>     可查看我写的Func教程:查看

Action 是个 void的委托,其中T1,T2..T8都是方法的参数,而Func是个,最后一个泛型参数是返回值,前面是方法的参数,例如Func<int,string,double> 那么最后一个double就是返回值类型,前面是方法签名的参数,等同于定义了

delegate double Method1(int,string);

关于Func可以写出很多很精彩的代码,真的很期待大家的发挥。

1.3  多播委托

如1.1示例1讲解的就是一个多播委托的简单的例子。

aaronyang的认识: 一个委托绑定了多个方法,然后执行委托,如果委托定义的方法签名是void,则依次执行,如果报错,迭代就停止。如果委托定义的方法签名有返回值,例如像int,string等类型,就只会看到最后一个结果。委托可以使用+=增加方法调用,使用

-=删除方法调用。

接下来,演示个Delegate类的GetInvocationList()方法返回一个Delegate数组

1.4 匿名方法其实在1.3我们已经见过了,直接 (方法参数)=>{ 方法体}   来简易的 定义一个方法类型。如果只有一个方法参数,括号可以去掉,例如 x=>{方法体}

也可以稍微烦一点的写法, 增加一个delegate关键字,例如  Func<string,string> a=delegate(string s){ return s} 也等同于  Func<string,string> a = s=>{return s} 也等同于   Func<string,string> a = s =>"修饰后:"+s;

1.5 闭包:Lambda表达式可以访问Lambda表达式外的变量;可能问题:假如多线程环境,修改了lambdawai的变量值,会使结果可能不正确了。

            int lambdawai = ;
Func<int,int> f = x => x+lambdawai;
Console.WriteLine(lambdawai); // 输出 5;
Console.WriteLine(f()); // 输出 8;

*1.6  C# 5.0很大的改变,foreach语句的闭包    参考文章:文章

个人小试:Win8.1 没发现。。问题

案例:下面代码输出什么,C#4.0 输出5,5,5,5,5   C#5.0输出1,2,3,4,5

            int[] data = new int[] { , , , ,  };
List<Func<int>> actions = new List<Func<int>>();
foreach (int x in data)
{
actions.Add(() => x);
}
foreach (var foo in actions)
{
Console.WriteLine(foo());
}

C# 4.0 foreach执行原理:的确输出5个5

   int[] data = new int[] { , , , ,  };
List<Func<int>> actions = new List<Func<int>>();
IEnumerator e = data.GetEnumerator(); int x = ;
while (e.MoveNext())
{
x = (int)e.Current;
actions.Add(() => x);
} foreach (var foo in actions)
{
Console.WriteLine(foo());
}

注意迭代变量x是在循环块外部被定义的。
这里涉及到一个很重要的概念,闭包,在Lambda表达式中,我们使用了外层的自由变量x,注意,在调用lambda表达式的时候,x会被求值,而这个定义在外部的x变量在循环终了等于5,这是为什么都是输出5的原因

C# 5.0 foreach执行原理:的确 1,2,3,4,5

            int[] data = new int[] { , , , ,  };
List<Func<int>> actions = new List<Func<int>>();
IEnumerator e = data.GetEnumerator(); while (e.MoveNext())
{
int x = ;
x = (int)e.Current;
actions.Add(() => x);
} foreach (var foo in actions)
{
Console.WriteLine(foo());
}

这一次,我们将x定义到块的内部。因此每当循环执行一次,都会产生一个局部变量x,闭包就会对每一个迭代单独求值,所以输出就是我们期望的12345了

如果想要得到1,2,3,4,5,可以修改代码:

            int[] data = new int[] { , , , ,  };
List<Func<int>> actions = new List<Func<int>>();
foreach (int x in data)
{
int x1 = x;
actions.Add(() => x1);
}
foreach (var foo in actions)
{
Console.WriteLine(foo());
}

1.7 事件-特殊的委托,例如winform的button的Click事件

自定义事件,泛型事件的调用,事件侦听器,弱性事件,泛型弱性事件,Expression的用法,内容很多,将在下一章单独讲吧。

留个问题:单个委托绑定2次相同的方法,执行该委托,方法会执行几次

例如 A+=a;A+=a;A();

======安徽六安=========www.ayjs.net==========aaronyang========杨洋========www.8mi.me==========

[AaronYang]C#人爱学不学[7]的更多相关文章

  1. [AaronYang]C#人爱学不学[1]

    当前编写时间:2014年12月24日21:11:14   编写人:杨洋(Aaronyang) 新文章:[AaronYang]C#人爱学不学[1] 声明:->可以理解为 联想到,或者关联的意思. ...

  2. [AaronYang]C#人爱学不学[6]

    不要回头,不要将就,做到这两点,人生就会简单很多幸福很多 --Aaronyang的博客(www.ayjs.net)-www.8mi.me 1. 运算符,还有哪些你能学到? 1.1 不安全运算符: si ...

  3. [AaronYang]C#人爱学不学[4]

    本文章不适合入门,只适合有一定基础的人看.我更相信知识细节见高低,我是从4.0开始学的,终于有时间系统的学习C#5.0,是5.0中的知识,会特殊标记下.但写的内容也可能含有其他版本framework的 ...

  4. [AaronYang]C#人爱学不学[3]

    本文章不适合入门,只适合有一定基础的人看.我更相信知识细节见高低,我是从4.0开始学的,终于有时间系统的学习C#5.0,是5.0中的知识,会特殊标记下.但写的内容也可能含有其他版本framework的 ...

  5. [AaronYang]C#人爱学不学8[事件和.net4.5的弱事件深入浅出]

    没有伟大的愿望,就没有伟大的天才--Aaronyang的博客(www.ayjs.net)-www.8mi.me 1. 事件-我的讲法 老师常告诉我,事件是特殊的委托,为委托提供了一种发布/订阅机制. ...

  6. [AaronYang]C#人爱学不学[5]

    这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 --Aaronyang的博客(www.ayjs.net) 1. 数组-的疑惑? 1.1  多维数组      ...

  7. [AaronYang]C#人爱学不学[2]

    1. 记事本写C#,脱离vs 新建记事本,名字为 helloworld.cs using System; namespace Hello{ public class HelloWorldSay{ st ...

  8. AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享

    原文:AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Te ...

  9. AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享

    原文:AY写给国人的教程- VS2017 Live Unit Testing[2/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Te ...

随机推荐

  1. Linux系统之用户、群组和权限

    一.用户管理 创建用户时,系统为用户分配一个唯一的编号UID,同时为用户创建一个同名的组,并为组分配一个编号GID,并把该用户加入该组中. 系统规定: uid: 0       特权用户      u ...

  2. 设置html的div中背景图片长宽

    使用以下可行 background-size:1040px 482px;

  3. [转]How to insert a row between two rows in an existing excel with HSSF (Apache POI)

    本文转自:http://stackoverflow.com/questions/5785724/how-to-insert-a-row-between-two-rows-in-an-existing- ...

  4. OpenXml入门----给Word文档添加文字

    使用OpenXml给word文档添加文字,每个模块都有自己对于的属性以及内容,要设置样式就先声明属性对象,将样式Append到属性里面,再将属性append到模块里面,那么模块里面的内容就具备该样式了 ...

  5. Golang 实现简单的滚动读取文本更新

    这个小程序要实现的效果,简单地说,就是将目标文件的内容读取输出到终端,并且目标文件并不是静态的,而是随时会添加新的内容.我们的目标就是一旦目标文件添加了新的内容,就把它读取出来并且显示到终端上. 实现 ...

  6. POJ 2653 Pick-up sticks --队列,几何

    题意: 按顺序扔木棒,求出最上层的木棒是哪些. 解法: 由于最上层的木棒不超过1000个,所以用一个队列存储最上层的木棒,每次扔出一个木棒后,都与队列中的木棒一一判断,看此木棒是否在某一最上层的木棒的 ...

  7. POJ 2318 TOYS【叉积+二分】

    今天开始学习计算几何,百度了两篇文章,与君共勉! 计算几何入门题推荐 计算几何基础知识 题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉. 有m个玩具(可以看成点)放在这 ...

  8. LoadRunner参数化MySQL

    准备:安装[msql-ODBC驱动] 一.配置数据源 1.Win7,打开控制面板-系统和安全-管理工具,点击“数据源(ODBC)”. 打开数据源(ODBC),在用户DSN选项卡中点击“添加”按钮,弹出 ...

  9. 在同一个机器中安装LoadRunner与QTP

    若你计划在测试机上安装LoadRunner并且测试机上已经安装了QTP,类似这样的情况可能会出现一些冲突现象,若QTP与LR必须并存在同一测试机上,那么请确保先安装Loadrunner以及所有的LR补 ...

  10. Python-装饰器详解

    初学python,装饰器是什么玩意儿? 1:装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 2:至少两层函数 方式一: 理解方式 ...