=============================Ch19~22 事件=============================
事件模型的五个组成部分
1.事件拥有者event source,对象
2.事件成员event,成员
3.事件响应者event subscriber,对象
4.事件处理器event handler,成员,本质是一种回调方法
5.事件订阅,关联事件处理器与事件,本质是一种委托为基础的约定
timer.Elapsed+=boy.Action;
事件处理器应当自动生成(按下Ctrl+.)来自动补全Action的参数
同一个Click事件可以被不同的空间重用
private void ButtonClicked(object sender,EventArgs e)
{
if(sender==this.button1)
{
//要做的事
}
if(sender==this.button2)
{
//要做的事
}
}
窗体控件的事件属性上右键可以Reset事件
将事件与方法挂接
方法1
this.button3.Click+=new EventHandler(this.ButtonClicked);
方法2 委托
this.button3.Click+=delegate(object sender,EventArgs e)
{this.textBox.Text="";}//匿名方法
方法3 Lambda表达式
this.button3.Click+=(sender,e)=>{this.textBox.Text="";}
自定义时间
声明委托类型和委托字段
委托属于数据类型的一种
委托声明的文本级别与类同级
事件的声明事件的声明
完整声明
简略声明(字段式声明,field-like)
有了委托字段/属性,为什么还需要事件?
为了程序的逻辑更加“有道理”、更加安全,谨防“借刀杀人”
所以事件的本质是委托字段的一个包装器
,这个包装器对委托字段的访问起限制作用,
相当于一个“蒙板”
封装(encapsulation)的一个重要功能就是隐藏
事件对外界隐藏了委托实例的大部分功能
仅暴露添加/移除事件处理器的功能
用于声明事件的委托类型的命名约定
用于声明Foo事件的委托,一般命名为FooEventHandler(除非是一个非常通用的事件约束)
FooEventHandler委托的参数一般有两个(由Win32 API演化而来,历史悠久)
第一个是object类型,名字为sender,实际上就是事件的拥有者、事件的source。
第二个是EventArgs类的派生类,类名一般为FooEventArgs,参数名为e。也就是前面讲过的事件参数
虽然没有官方的说法,但我们可以把委托的参数列表看做是事件发生后发送给事件响应者的“事件消息
触发Foo事件的方法一般命名为OnFoo,即“因何引发”、"事出有因
访问级别为protected,不能为public,不然又成了可以“借刀杀人”了
事件的命名约定
带有时态的动词或者动词短语
事件拥有者“正在做"什么事情,用进行时;事件拥有者“做完了“什么事情,用完成时
=============================Ch23 泛型 委托 Lambda LINQ=============================
委托是一系列方法的封装
委托声明
delegate int MyDele(int a,int b);
被委托方法
static int Add(int x,int y)
{
return x+y;
}
委托调用
MyDele dele=new MyDele(Add);
int result=dele(100,200);
泛型委托
委托声明
delegate T MyDele<T>(T a,T b);
被委托方法
static int Add(int x,int y)
{
return x+y;
}
static double Mul(double x,double y)
{
return x*y;
}
委托调用
MyDele<int> dele=new MyDele<int>(Add);
int result=dele(100,200);
MyDele<double> Muldele=new MyDele<double>(Mul);
double result=Muldele(100,200);
Action关键词
普通Action只能调用无返回值且参数列表为空的方法
static void M1(){}
Action action=new Action(M1);
action();
泛型Action可以调用含参方法
static void SayHello(string name)
{
Console.WriteLine($"Hello,{name}!");
}
Action<string> action=new Action<string>(SayHello);
action("Tim");
Lambda表达式
1.匿名方法
2.Inline方法(边用边定义)
Func<int,int,int> func=new Func<int,int,int>((int a,int b)=>{return a+b;});
简略写法
Func<int,int,int> func=(a,b)=>{return a+b;};
Lambda表达式与泛型、委托(Func)
声明
static void DoSomeCalc<T>(Func<T,T,T> func,T x,T y){T res=func(x,y);}
调用
DoSomeCalc<int>((int a,int b)=>{return a*b;},100,200);
省略调用,泛型委托的参数推断
DoSomeCalc((a,b)=>{return a*b;},100,200);
LINQ
.NET Language Integrated Query
查询
var dbContext=new AdventureWorks2014Entities();
var count=dbContext.People.Count(p=>p.FirstName=="Timothy");
Console.WriteLine(count);
Count的定义声明
int IQueryable<Person>.Count<Person>
(System.Linq.Expressions.Expression<func<Person,bool>>predicate)
=============================Ch26 重写与多态=============================
JetBrains Rider编译器
.NET Core跨平台
www.edx.org timothy liu查询课程
ECMA C# 标准化(委员会)版本