MVCJamespart1新语法.docx
- 文档编号:18058683
- 上传时间:2023-08-07
- 格式:DOCX
- 页数:16
- 大小:359.20KB
MVCJamespart1新语法.docx
《MVCJamespart1新语法.docx》由会员分享,可在线阅读,更多相关《MVCJamespart1新语法.docx(16页珍藏版)》请在冰点文库上搜索。
MVCJamespart1新语法
01.新语法
本章中主要讲解.Net框架性语法。
开发者可以使用新语法提高编程的效率以及代码的运行效率;其本质都是“语法糖”,由编译器在编译时转成原始语法。
◆自动属性Auto-ImplementedProperties
◆隐式类型var
◆对象初始化器与集合初始化器{}
◆匿名类&匿名方法
◆扩展方法
◆系统内置委托Func/ActionPredicate(bool(T))/Comparison(int(T,T))
◆Lambda表达式
◆标准查询运算符Standardqueryoperator
◆LINQ查询表达式
Mvc框架简介:
浏览器请求服务器的某个控制器类的Action方法,方法中可以调用业务层等代码处理业务,并产生数据Model,交给
视图引擎,视图引擎会找到对应视图,并将数据“填充到“视图上对应的位置,最终产生整个页面的Html代码,返回给浏览器。
关于编译器:
编译器会在编译的时候,按照C#语法检查代码,C#语法规定变量只能调用其声明类型的成员,如果声明是父类,则只能调用对象里的父类成员
自动属性
回顾传统属性概念
属性的目的:
封装字段,控制1.读写权限及2.字段的访问规则(如:
年龄范围)。
但平时,主要是用来封装读写权限。
回顾语法:
缺点,臃肿,代码难看!
麻烦!
intid;//字段
publicintId//属性
{
get{returnid;}
set{id=value;}
}
◆自动属性语法:
只需要定义无实现的属性语法即可,不需要定义字段。
publicintId{get;set;}
publicintAge{get;set;}
publicstringName{get;set;}
◆查看源码:
编译后,也生成了对应的属性语法(get和set方法)
但同时,帮我们生成了一个私有变量
总结:
自动属性主要用在对字段的读写权限的封装,帮助减少程序员代码,让代码更好看;但实质上在编译时,还是会自动生成一个对应的字段的。
所以,从这个意义上说,自动属性就相当于是微软提供的一个“语法糖”了。
◆思考:
用自动属性程序员写的代码少了,机器做的事情就多了,那我们到底要不要使用它?
如果是针对读写权限的封装,就推荐使用,因为它是在编译的时候产生了负担,并不是在运行的时候。
(不会影响客户运行程序时的效率!
)
但是编译生成的代码也有一个显而易见的缺点,语法太完整,编译后的程序集会比较大。
隐式类型var
回顾,传统变量定义方式:
intage=11;//传统方式
◆隐式类型:
在初始化时,就已经根据=右边的值确定了var变量的类型了。
varage1=12;
//age1="123";
varname="哈哈哈";
vardog=newDog();
age1=123;
name="刘德华";
dog.Id=11;
编译时,已经把var转成了相应的类型了。
注意:
1.声明的同时必须初始化,因为编译时要根据初始化值类型来推断var;
2.声明后不能修改数据类型,因为初始化时已经确定了var类型了;
3.只能作为方法局部变量使用。
类的成员字段、方法的形参和返回值都不能使用!
因为无法编译时确定他们的类型!
4.初始化表达式不能是匿名函数和null。
◆查看源码:
var已经不存在了,都被替换成了初始化值的类型。
对象/集合初始化器
回顾:
List
{
List
for(inti=0;i<10;i++)
{
Dogd=newDog();
d.Id=i;
d.Name="Ruiky"+i;
d.Age=i*2;
d.Toy=newDogToy();
d.Toy.ToyId=i;
d.Toy.ToyName="狗狗玩具"+i;
list.Add(d);
}
returnlist;
}
对象集合初始化器语法:
用法1
List
{
List
for(inti=0;i<10;i++)
{
Dogd=newDog
{
Id=i,
Name="Ruiky"+i,
Age=i*2,
Toy=newDogToy()//使用属性初始化器
{
ToyId=i,
ToyName="狗狗玩具"+i
}
};
list.Add(d);
}
returnlist;
}
//用法2
List
{
List
newDog(){Id=1,Name="Ruiky",Age=1,Toy={ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy={ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy={ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy={ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy={ToyId=1,ToyName="小球"}}
};
returnlist;
}
用初始化器,创建数组!
Dog[]dogs={
newDog(){Id=1,Name="Ruiky",Age=1,Toy=newDogToy{ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy=newDogToy{ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy=newDogToy{ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy=newDogToy{ToyId=1,ToyName="小球"}},
newDog(){Id=1,Name="Ruiky",Age=1,Toy=newDogToy{ToyId=1,ToyName="小球"}}
};
查看源码:
可以看到,编译器帮我们实例化的集合或者数组,并创建了元素对象,设置给数组或集合。
匿名类
回顾:
◆匿名类语法:
a.避免过度的数据累积
b.为一种情况特别进行的数据封装
c.避免进行单调重复的编码
varobj=new
{
Id=1,
Name="Ruiky",
Age=2
};
◆查看源码:
1.编译器自动为这个【匿名类】创建了一个无命名空间的类型。
2.在new关键字处,创建该匿名类对象
3.编译器创建的匿名类结构
◆注意:
1.当出现“相同”的匿名类的时候,编译器只会创建一个匿名类
2.编译器如何区分匿名类是否相同?
根据:
属性名,属性值(因为这些属性是根据值来确定类型的),
属性个数,属性的顺序。
匿名方法
回顾:
普通方法定义方式,因为方法的存在是为了复用一段代码,所以一般会给方法取个名字,这个方法的引用就可以通过"方法名"调用。
voidTest()
{
Console.WriteLine("哈哈哈~!
");
}
匿名方法:
但是有的方法,不需要复用,仅仅是使用一次就够了,所以不需要方法名,这种方法就叫做匿名方法。
匿名方法必须结合委托使用。
(潜在的意思就是:
尽管没有方法名了,但方法的指针还是存放在了某个委托对象中)
如,现在为线程指定要执行的方法的时候,就可以使用匿名方法了。
◆注意:
1.在编译后,会为每个匿名方法创建一个私有的静态方法,然后将此静态方法传给委托对象使用。
扩展方法
为什么要有扩展方法?
就是为了在不修改源码的情况下,为某个类增加新的方法。
◆语法:
定义静态类,并添加public的静态方法,第一个参数代表扩展方法的扩展类。
a)它必须放在一个非嵌套、非泛型的静态类中(的静态方法);
b)它至少有一个参数;
c)第一个参数必须附加this关键字;
d)第一个参数不能有任何其他修饰符(out/ref)
e)第一个参数不能是指针类型
publicstaticclassDogExtention
{
publicstaticstringSayHi(thisDogdogObj)
{
returnstring.Format("哈哈哈哈~~~我叫{0}!
",dogObj.Name);
}
}
//-----------------------
//使用扩展方法
Dogd=newDog(){
Id=1,Name="0094",Age=11,
Toy=newDogToy(){ToyId=1,ToyName="小骨头"}
};
stringstr=d.SayHi();//调用扩展方法,此时的对象d就作为第一个参数传到了扩展方法中
编译后:
stringstr=DogExtention.SayHi(d);
◆注意:
1.当我们把扩展方法定义到其它程序集中时,一定要注意调用扩展方法的环境中包含扩展方法所在的命名空间。
如,在Extention下为String类添加一个扩展方法
然后在页面中使用时,要记得导入命名空间,否则调用不到扩展方法:
2.扩展方法需要使用特性ExtensionAttribute,当前程序中必须包含程序集ComplilerServices,否则报错如下:
注:
此程序集默认在FrameWork3.5开始自动包含。
3.因为扩展方法的本质是被编译后替换成静态方法,所以对象本身可以为null,但是在这个扩展方法中,如果访问了第一个参数,则会报“空指针异常”。
◆查看源码:
1.通过源码看到,在执行stringstr=d.SayHi();的地方,编译后变成了这个扩展方法通过静态类的调用方式代码。
由此可见,扩展方法并没有被"扩展"到Dog类中,只不过是在编译的时候替换成了静态类里的静态方法而已。
d.SayHi()就是一个语法糖!
◆思考:
如果Dog类中本身就包含SayHi方法,那会怎么样?
但同时包含同名的实例方法和扩展方法时,优先调用实例方法。
泛型委托
◆回顾通过【比较接口】方式:
让Dog集合根据Dog的id排序,需要写一个IComparer
接口:
实现类(比较器):
然后将实现类对象传入集合的Sort方法:
◆使用泛型委托+匿名方法实现:
List
publicvoidSort(Comparison
看看这个Comparison
publicdelegateintComparison
修改调用的方法:
◆常用系统泛型委托:
1.System.Func代表有返回类型的委托
publicdelegateTResultFunc
publicdelegateTResultFunc
......
注:
输入泛型参数-in最多16个,输出泛型参数-out只有一个。
2.System.Action代表无返回类型的委托//list.ForEach
publicdelegatevoidAction
publicdelegatevoidAction
......
注:
参数最多16个
3.System.Predicate
publicdelegateboolPredicate
4.System.Comparison
publicdelegateintComparison
关于泛型委托的泛型参数列表的in和out
//泛型委托的in泛型参数代表可以被作为参数列表的类型
//out泛型参数代表可以被作为返回值的类型
publicdelegateT2DgSay
Lambda表达式
回顾,发现上面的代码,需要传一个匿名方法,写起来特别别扭。
能否有简化的语法呢?
有!
Lambda表达式。
概念:
Lambda表达式有两种:
语法:
List
//list.FindAll(delegate(Dogd){returnd.Id>2;});
//1.表达式Lambda
list.FindAll(d=>d.Id>2);//goesto
list.ForEach(d=>Response.Write(d.ToString()+"
"));
//2.语句Lambda
list.ForEach(d=>{if(d.Id>2)Response.Write(d.ToString()+"
");});
语法进化史:
查看源码:
C#语法:
list.FindAll(d=>d.Id>2);
编译成中间代码后,代码太多,简而言之如下:
编译器帮我们:
1.声明一个Predicate
2.创建一个私有的符合委托签名的静态方法;
3.实例化委托变量,并将方法传入;
4.调用list.FindAll方法,并传入委托变量。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MVCJamespart1 语法
![提示](https://static.bingdoc.com/images/bang_tan.gif)