从 C# 1.0 到 C# 3.0 委托创建过程的发展:
delegate void TestDelegate(string s);
// C# 1.0 :Original delegate syntax required
TestDelegate testDelA = new TestDelegate(M);
// C# 2.0: A delegate can be initialized with
TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };
// C# 3.0. A delegate can be initialized with
TestDelegate testDelC = (x) => { Console.WriteLine(x); };
委托的使用
委托实现了面向对象的,类型安全的方法回调机制。
int a
委托可以看成一种数据类型。可以定义变量,其定义的变量接收的数值只能是函数
委托,实现了类型安全的回调方法
1.声明委托
public delegate int hellodelegate(int a ,int b)
2.根据委托,定义具体方法
二者具有相同的返回值类型和参数列表
public int add(int a,int b)
{
return a+b;
}
3,创建委托对象关联具体函数(创建委托变量并赋值)
hellodelegate hello=new hellodelegate(add);
或者
hellodelegate hello;
hello= new hellodelegate(add);
4,通过委托调用方法
hello变量保存了指向 Add 方法的引用,以此实现对 Add 的回调。
hello(1,2);
5,断开所关联的方法
hello-=add;
6,重新关联新的方法
hello+=sum;
多播 委托链
将多个方法绑定到一个委托变量,在调用一个方法时,可以依次执行其绑定的所有方法,这种技术称为多播委托
myDelegate = new CalculateDelegate(Add);
myDelegate += new CalculateDelegate(Subtract);
myDelegate += new CalculateDelegate(Multiply);
myDelegate(100, 200);
依次输出
300,-100 20000
事实上,+=和-=操作分别调用了 Deleagate.Combine 和 Deleagate.Remove 方法,
另外,多播委托返回值一般为 void,委托类型为非 void 类型时,多播委托将返回最后一个调 用的方法的执行结果,所以在实际的应用中不被推荐
委托本质上仍旧是一个类,该类继承自 System.MulticastDelegate 类,该类维护一个带有链接的委托列表,在调用多播委托时,将按照委托列表的委托顺序而调用的。还包括一个接受两个参数的构造函数和 3 个重要方法:BeginInvoke、EndInvoke 和 Invoke。
事件
事件是对委托的封装,
C#中的三种委托方式:Func委托,Action委托,Predicate委托。
Func委托有如下的5种类型:
(1) *delegate TResult Func();
(2)*delegate TResult Func(T1 arg1);
(3) *delegate TResult Func(T1 arg1,T2 arg2);
(4)*delegate TResult Func(T1arg1, T2 arg2, T3 rg3);
(5)*delegate TResult FuncT1arg1, T2 arg2, T3 arg3, T4 arg4);
Action委托
Action委托的几种表现形式:
(1) * delegatevoid Action(); 无参,无返回值
(2)* delegatevoid Action(T1 arg1);
(3)* delegatevoid Action(T1 arg1, T2 arg2);
(4)* delegatevoid ActionT1 arg1, T2 arg2, T3 arg3);
(5)* delegatevoid ActionT1 arg1, T2 arg2, T3 arg3, T4 arg4);
这个委托也是非常常用的,尤其是在涉及到线程和界面交互的时候,配合着lamada表达式使用,非常方便的实现二者的交互
Predicate委托,
这个的形式比较少一些,就是一个传入参数,返回值为bool类型
总结
Func可以接受0个至4个传入参数,必须具有返回值
Action可以接受0个至4个传入参数,无返回值
Predicate只能接受一个传入参数,返回值为bool类型
如何在WinForm中利用这些委托进行线程和界面的交互。
#region利用Func实现线程和界面交互
private void AlternationUsingFunc(object text)
{
//无参数,但是返回值为bool类型
this.Invoke(new Func(delegate()
{
button1.Text =text.ToString();
return true; //返回值
}));
}
privatevoid AlternationUsingFuncThread()
{
//WaitCallback 委托是将任务排入队列以供线程池执行,
WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingFunc);
ThreadPool.QueueUserWorkItem(waitCallBack, "Func的使用");
}
privatevoid button1_Click(object sender, EventArgs e)
{
AlternationUsingFuncThread();
}
#endregion
Lambda表达式
Lambda 表达式本质上就是一种匿名委托
linq 面向对象的查询语言 查询语句通过编程语言自身来表达,而不是嵌入sql语句
分为三部分
1.linq to Object
2.Linq to XML
3.Linq to SDO.NET
- Linq to SQL
- linq to dataset
- linq to entities
查询方法
select 是泛型扩展方法
要求传递一个委托实例,具体的方法。
返回结果是个迭代器
where 是泛型扩展方法,
要求传入委托实例
返回bool类型
orderby
要去传递一个字段
groupby
要求传递一个分组的字段
链式编程 连续使用特定方法
延迟执行
定义查询后并没有立即执行而是等到需要枚举结果时才被真正执行
使用聚合扩展方法,返回单一结果会强制立即执行。.where.。count
查询语句 类似于SQL语言 但最终执行时还是会被转换为查询方法
部分方法没有查询语句 conut max 等聚合方法。