Net学习日记_ASP.Net_MVC_新语法笔记
01.新语法
本章中主要讲解.Net框架性语法。开发者可以使用新语法提高编程的效率以及代码的运行效率;其本质都是“语法糖”,由编译器在编译时转成原始语法。
1 自动属性 Auto-Implemented Properties
2 隐式类型 var
3 对象初始化器 与 集合初始化器 { }
4 匿名类 & 匿名方法
5 扩展方法
6 系统内置委托 Func / Action Predicate (bool (T)) / Comparison (int (T,T))
7 Lambda表达式
8 标准查询运算符 Standard query operator
9 LINQ查询表达式
Mvc框架简介:
浏览器请求 服务器的 某个控制器类 的 Action方法,方法中可以调用业务层等代码处理业务,并产生数据Model,交给视图引擎,视图引擎会找到对应视图,并将数据 “填充到“视图上对应的位置,最终产生整个页面的Html代码,返回给浏览器。
关于编译器:
编译器会在编译的时候,按照C#语法检查代码,C#语法规定变量只能调用其声明类型的成员,如果声明是父类,则只能调用对象里的父类成员
自动属性
回顾传统属性概念
属性的目的:封装字段,控制 1.读写权限 及 2.字段的访问规则(如:年龄范围)。
但平时,主要是用来封装 读写权限。
回顾 语法:缺点,臃肿,代码难看!麻烦!
int id; //字段 public int Id //属性 {get { return id; }set { id = value; } }
自动属性 语法:只需要定义 无实现的属性语法 即可,不需要定义字段。
public int Id { get; set; } public int Age { get; set; } public string Name { get; set; }
查看源码:
编译后,也生成了对应的属性语法(get和set方法)
但同时,帮我们生成了一个私有变量
总结:
自动属性主要用在对 字段的 读写权限的封装,帮助减少程序员代码,让代码更好看;但实质上在编译时,还是会自动生成一个对应的字段的。
所以,从这个意义上说,自动属性就相当于是微软提供的一个“语法糖”了。
思考:
用自动属性程序员写的代码少了,机器做的事情就多了,那我们到底要不要使用它?
如果 是针对 读写权限的封装,就推荐使用,因为它是在编译的时候产生了负担,并不是在运行的时候。(不会影响客户运行程序时的效率!)
但是编译生成的代码也有一个显而易见的缺点,语法太完整,编译后的程序集会比较大。
隐式类型var
回顾,传统变量定义方式:
int age = 11;//传统方式
隐式类型:在初始化时,就已经根据 = 右边的 值 确定了 var变量的类型了。
var age1 =12; //age1="123"; var name = "哈哈哈"; var dog = new Dog();age1 = 123; name = "刘德华"; dog.Id = 11;
编译时,已经 把var 转成了 相应的类型了。
注意:
1.声明的同时必须初始化,因为编译时要根据初始化值类型来推断var;
2.声明后不能修改数据类型,因为初始化时已经确定了var类型了;
3.只能作为方法局部变量使用。类的成员字段、方法的形参和返回值都不能使用!因为无法编译时确定他们的类型!
4.初始化表达式不能是匿名函数和null。
查看源码:var 已经不存在了,都被替换成了 初始化值 的 类型。
对象/集合初始化器
List<Dog> InitList() {List<Dog> list = new List<Dog>();for (int i = 0; i < 10; i++){Dog d = new Dog();d.Id = i;d.Name = "Ruiky" + i;d.Age = i * 2;d.Toy = new DogToy();d.Toy.ToyId = i;d.Toy.ToyName = "狗狗玩具" + i;list.Add(d);}return list; }
对象集合初始化器语法:
用法1List<Dog> InitList(){List<Dog> list = new List<Dog>();for (int i = 0; i < 10; i++){Dog d = new Dog{Id = i,Name = "Ruiky" + i,Age = i * 2,Toy = new DogToy()//使用属性初始化器 {ToyId = i,ToyName = "狗狗玩具" + i}};list.Add(d);}return list;}//用法2List<Dog> InitList(){List<Dog> list = new List<Dog>{new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = { ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = { ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = { ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = { ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = { ToyId=1, ToyName="小球"}}};return list;}
用初始化器,创建数组!
Dog[] dogs = {new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = new DogToy{ ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = new DogToy{ ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = new DogToy{ ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = new DogToy{ ToyId=1, ToyName="小球"}},new Dog(){ Id=1, Name="Ruiky", Age=1, Toy = new DogToy{ ToyId=1, ToyName="小球"}} };
查看源码:可以看到,编译器帮我们实例化的集合或者数组,并创建了元素对象,设置给数组或集合。
匿名类
回顾:
匿名类语法:
a.避免过度的数据累积
b.为一种情况特别进行的数据封装
c.避免进行单调重复的编码
var obj = new{Id = 1,Name = "Ruiky",Age = 2};
查看源码:
1.编译器自动为 这个 【匿名类】 创建了一个无命名空间的类型。
2.在new 关键字处,创建该匿名类对象
3.编译器创建的匿名类结构
注意:
1. 当出现“相同”的匿名类的时候,编译器只会创建一个匿名类
2. 编译器如何区分匿名类是否相同?
根据:
属性名,属性值(因为这些属性是根据值来确定类型的),
属性个数,属性的顺序。
匿名方法
回顾:普通方法定义方式,因为方法的存在是为了 复用 一段代码,所以一般会给方法取个名字,这个方法的引用就可以通过 "方法名"调用。
void Test(){Console.WriteLine("哈哈哈~!");}
匿名方法:但是有的方法,不需要复用,仅仅是使用一次就够了,所以不需要方法名,这种方法就叫做匿名方法。
匿名方法必须结合 委托 使用。(潜在的意思就是:尽管没有方法名了,但方法的指针还是存放在了某个委托对象中)
如,现在为线程指定要执行的方法的时候,就可以使用匿名方法了。
注意:
1.在编译后,会为每个匿名方法创建一个 私有的静态方法,然后将此静态方法传给 委托对象使用。
扩展方法
为什么要有扩展方法? 就是为了在不修改源码的情况下,为某个类 增加新的方法。
语法:
定义静态类,并添加public的静态方法,第一个参数 代表 扩展方法的扩展类。
a) 它必须放在一个非嵌套、非泛型的静态类中(的静态方法);
b) 它至少有一个参数;
c) 第一个参数必须附加 this 关键字;
d) 第一个参数不能有任何其他修饰符(out/ref)
e) 第一个参数不能是指针类型
public static class DogExtention{public static string SayHi(this Dog dogObj){return string.Format("哈哈哈哈~~~我叫{0}!", dogObj.Name);} } //----------------------- //使用扩展方法 Dog d = new Dog() { Id = 1, Name = "0094", Age = 11, Toy = new DogToy() { ToyId=1, ToyName="小骨头" } }; string str = d.SayHi();//调用扩展方法,此时的对象d就作为第一个参数传到了扩展方法中 编译后: string str = DogExtention.SayHi(d);
注意:
1.当我们把扩展方法定义到其它程序集中时,一定要注意调用 扩展方法的环境中包含 扩展方法所在的命名空间。如,在Extention下为String类添加一个扩展方法
然后在页面中使用时,要记得导入命名空间,否则调用不到扩展方法:
2.扩展方法需要使用特性ExtensionAttribute,当前程序中必须包含程序集ComplilerServices,否则报错如下:
注:此程序集默认在FrameWork3.5开始自动包含。
3.因为扩展方法的本质是被编译后替换成静态方法,所以 对象本身 可以为 null,但是在这个扩展方法中,如果访问了第一个参数,则会报“空指针异常”。
查看源码:
1.通过源码看到,在执行 string str = d.SayHi();的地方,编译后变成了 这个扩展方法通过静态类的调用方式代码。由此可见,扩展方法并没有被"扩展"到Dog类中,只不过是在编译的时候替换成了静态类里的静态方法而已。d.SayHi()就是一个语法糖!
思考:如果 Dog类中本身就包含 SayHi方法,那会怎么样?
但同时包含同名的 实例方法 和 扩展方法时,优先调用实例方法。
泛型委托
回顾通过【比较接口】方式:
让 Dog集合 根据Dog的id排序,需要写一个IComparer<Dog>接口的实现类,在类中重写 接口的 Compare方法,来返回 正整数/0/负整数。
接口:
实现类(比较器):
然后将实现类对象传入集合的Sort方法:
使用泛型委托 + 匿名方法实现:
List<T>集合类中包含 新的排序方法,根据 泛型委托Comparison<T> 完成比较过程。
public void Sort(Comparison<T> comparison);
看看这个Comparison<T> 泛型委托:
public delegate int Comparison<in T>(T x, T y);
修改调用的方法:
常用系统泛型委托:
1.System.Func 代表有返回类型的委托 public delegate TResult Func<out TResult>(); public delegate TResult Func<in T, out TResult>(T arg); ...... 注:输入泛型参数-in 最多16个,输出泛型参数 -out 只有一个。 2.System.Action 代表无返回类型的委托 //list.ForEach public delegate void Action<in T>(T obj); public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); ...... 注:参数最多16个 3.System.Predicate<T> 代表返回bool类型的委托 //list.Find public delegate bool Predicate<in T>(T obj); 4.System.Comparison<T> 代表返回int类型的委托 - 用作比较两个参数的大小 public delegate int Comparison<in T>(T x, T y); //list.Sort
关于泛型委托的泛型参数列表的 in 和 out
//泛型委托 的 in 泛型参数 代表 可以被作为 参数列表的类型 // out 泛型参数 代表 可以被作为 返回值的类型 public delegate T2 DgSay<in T,out T2>(T t1);
Lambda表达式
回顾,发现上面的代码,需要传一个 匿名方法 ,写起来特别别扭。
能否有简化的语法呢?有!Lambda表达式。
概念:
Lambda表达式有两种:
语法:
List<Dog> list = InitList(); //list.FindAll(delegate(Dog d) { return d.Id > 2; }); //1.表达式 Lambda list.FindAll(d => d.Id > 2);// goes to list.ForEach(d => Response.Write(d.ToString() + "<br/>"));//2.语句 Lambda list.ForEach(d => { if (d.Id > 2) Response.Write(d.ToString() + "<br/>"); });
语法进化史:
查看源码:
C#语法:list.FindAll(d => d.Id > 2);
编译成中间代码后,代码太多,简而言之如下:
编译器帮我们 :
1.声明一个 Predicate<Dog>委托变量;
2.创建一个私有的符合委托签名的静态方法;
3.实例化委托变量,并将方法 传入;
4.调用list.FindAll方法,并传入委托变量。
转载于:https://www.cnblogs.com/lisong-home/p/8207086.html
Net学习日记_ASP.Net_MVC_新语法笔记相关推荐
- 10.16 my学习日记 (XPath的基础语法,lxml库的应用)
10.16 my学习日记(XPath的基础语法,lxml库的应用) XPath的基础语法 XPath查找标签 XPath谓语 lxml库在爬虫中的应用 etree库etree_Element对象 使用 ...
- 十五的学习日记20160926-你不知道的JS笔记/
十五的学习日记20160926 JavaScript 一个用于检测正负值的函数,可以用它辨别-0值. 我觉得挺好用,以后可以写到自己的工具库里. //函数:检查传入参数是否为正数.Number=> ...
- Net学习日记_ASP.Net_一般处理程序_笔记
一.浏览器和服务器的交互简单原理 1.静态语言和动态语言 静态语言:在服务器端,不会被执行,直接作为 字符串 发回给浏览器,由浏览器运行的语言(HTML+CSS+JS). 动态语言:在服务端,会被服务 ...
- JavaScript学习日记(一)【笔记】
比较web三项 语言 作用 说明 html 结构 决定网页的结构和内容. css 样式 决定网页呈现给用户的模样 JavaScript 行为 实现业务逻辑和页面控制 基本认识 Java和JavaScr ...
- 学习C# 3.0语法笔记(1)
Conditional 条件编译符,早该想到,亏我以前一直写 #if XXX #elif XXX else XXX endif 转载于:https://www.cnblogs.com/canlove/ ...
- 正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
正则表达式学习日记_<学习正则表达式>笔记_Mr_Ouyang 所属分类: 正则表达式学习日记 书名: 学习正则表达式 作者: Michael Fitzgerald 译者 ...
- 【学习笔记】刘晓艳英语语法笔记(2/6)——并列句
前言: 本英语语法笔记是基于刘晓艳语法视频制作的,适合考研.专升本.专接本.想学习英语语法的朋友. 目录 1.什么是并列句?--用连词连接两个句子. 考点分析 2.完型填空 3.长难句分析: 1.什么 ...
- 安卓开发学习日记第二天_破坏陷阱卡之sync的坑_莫韵乐的快乐笔记
安卓开发学习日记第二天 前情提要:第一天的日记 经过第一天的日记,我们顺利第安装上了Android Studio3.6 第二天内容包括: 1.推荐的文件目录结构 2.如何创建一个项目 3.遇到sync ...
- 安卓开发学习日记第一天(笑)_Android Studio3.6安装_莫韵乐的快乐笔记
安卓开发学习第一天 Android Studio3.6安装 没想到终于要写出自己的第一个博客了 反正是第一篇,有没有人看都无所谓(理智:129/129) 万事开头难,做下去就容易很多了 言归正传 工欲 ...
最新文章
- 兄弟俩都是院士!哥哥在南大,弟弟在复旦
- 网络营销外包专员浅析响应式网站建设应注意哪些网络营销外包细节
- 从头开始敲代码之《从BaseApplication/Activity开始(二)》
- SAP UI5 click list item to navigate to detail page
- JDK 10:从Java访问Java应用程序的进程ID
- 4——编码规则以及vim的使用和虚拟环境
- Java语言实现查找最长前缀
- Adobe Creative Cloud 2022 (macOS、Windows) TNT 合集
- dart 爬取 妹子图 豆瓣影评
- 别踩白块儿游戏代码html,别踩白块儿.html · 知足常乐大哥哥/not-step-on-white-block - Gitee.com...
- ffmpeg实例,fade淡入淡出效果
- java排他_排他文件锁实现(Java版本)
- 【微机原理 实验】大小写字母的转换实验 (含汇编代码)
- 人工智能时代,如何让机器狗听懂你说的话?
- 详解Android布局中gravity与layout_gravity属性
- 金科股份称黄红云成被执行人和离婚有关,公司股价、毛利率均走低
- 2022年cfa一级二级三级网课资源
- bootstrap实现手风琴功能(树形列表)
- 多点解读贝泰妮:火速转战H股,女人的钱究竟有多好赚?
- twitter系统架构
热门文章
- php 判断ajax访问,PHP里判断是否Ajax请求
- arduino esp8266_你还用Arduino?上PlatformIO开发Esp、AVR、STM32,十分钟亲测ESP8266
- 信号的采样与恢复matlab实验报告,实验七 连续信号的采样与恢复
- php mysql 排名_mysql中如何实现排名
- spring boot整合shiro继承redis_spring-boot-plus集成Shiro+JWT权限管理
- php cookie 二级域名,php如何设置cookie对整个域名有效及二级域名
- android内部类broadcastreceiver,android 公开静态内部类BroadcastReceiver
- 实战 es6_腾讯云 Elasticsearch 实战篇(二十二) ES6.8权限使用配置
- java从数组中删除元素(数组的缩容)
- 正在从“vetur”获取代码操作_长时间运行 io.Reader 和 io.Writer 操作测算进度和估算剩余时间...