本节中主要学习.Net框架性语法。开发者可以使用新语法提高编程的效率以及代码的运行效率;其本质都是“语法糖”,由编译器在编译时转成原始语法。

u  自动属性 Auto-Implemented Properties

u  隐式类型 var

u  对象初始化器 与 集合初始化器 { }

u  匿名类 & 匿名方法

u  扩展方法

u  系统内置委托 Func / Action  Predicate (bool (T)) / Comparison (int (T,T))

u  Lambda表达式

u  标准查询运算符 Standard query operator

u  LINQ查询表达式

Mvc框架简介:

浏览器请求 服务器的 某个 控制器类 的 Action方法,方法中可以调用业务层等代码处理业务,并产生数据Model,交给

视图引擎,视图引擎会找到对应视图,并将数据 “填充到“视图上对应的位置,最终产生整个页面的Html代码,返回给浏览器。

关于编译器:

编译器会在编译的时候,按照C#语法检查代码,C#语法规定变量只能调用其声明类型的成员,如果声明是父类,则只能调用对象里的父类成员

自动属性

回顾传统属性概念

属性的目的:封装字段,控制 1.读写权限 及 2.字段的访问规则(如:年龄范围)。

但平时,主要是用来封装 读写权限。

回顾 语法:缺点,臃肿,代码难看!麻烦!

int id; //字段

public int Id //属性

{

get { return id; }

set { id = value; }

}

u  自动属性 语法:只需要定义 无实现的属性语法 即可,不需要定义字段。

public int Id { get; set; }

public int Age { get; set; }

public string Name { get; set; }

u  查看源码:

编译后,也生成了对应的属性语法(get和set方法)

但同时,帮我们生成了一个私有变量

总结:

自动属性主要用在对 字段的 读写权限的封装,帮助减少程序员代码,让代码更好看;但实质上在编译时,还是会自动生成一个对应的字段的。

所以,从这个意义上说,自动属性就相当于是微软提供的一个“语法糖”了。

u  思考:

用自动属性程序员写的代码少了,机器做的事情就多了,那我们到底要不要使用它?

如果 是针对 读写权限的封装,就推荐使用,因为它是在编译的时候产生了负担,并不是在运行的时候。(不会影响客户运行程序时的效率!)

但是编译生成的代码也有一个显而易见的缺点,语法太完整,编译后的程序集会比较大。

隐式类型var

回顾,传统变量定义方式:

int age = 11;//传统方式

u  隐式类型:在初始化时,就已经根据 = 右边的 值 确定了 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。

u  查看源码: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;

}

对象集合初始化器语法:

用法1

List<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;

}

//用法2

List<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="小球"}}

};

查看源码:可以看到,编译器帮我们实例化的集合或者数组,并创建了元素对象,设置给数组或集合。

匿名类

回顾:

u  匿名类语法:

a.避免过度的数据累积
b.为一种情况特别进行的数据封装
c.避免进行单调重复的编码

var obj = new

{

Id = 1,

Name = "Ruiky",

Age = 2

};

u  查看源码:

1.编译器自动为 这个 【匿名类】 创建了一个无命名空间的类型。

2.在new 关键字处,创建该匿名类对象

3.编译器创建的匿名类结构

u  注意:

1. 当出现“相同”的匿名类的时候,编译器只会创建一个匿名类

2. 编译器如何区分匿名类是否相同?

根据:

属性名,属性值(因为这些属性是根据值来确定类型的),

属性个数,属性的顺序。

匿名方法

回顾:

普通方法定义方式,因为方法的存在是为了 复用 一段代码,所以一般会给方法取个名字,这个方法的引用就可以通过 "方法名"调用。

void Test()

{

Console.WriteLine("哈哈哈~!");

}

匿名方法:

但是有的方法,不需要复用,仅仅是使用一次就够了,所以不需要方法名,这种方法就叫做匿名方法。

匿名方法必须结合 委托使用。(潜在的意思就是:尽管没有方法名了,但方法的指针还是存放在了某个委托对象中)

如,现在为线程指定要执行的方法的时候,就可以使用匿名方法了。

u  注意:

1.在编译后,会为每个匿名方法创建一个 私有的静态方法,然后将此静态方法传给 委托对象使用。

扩展方法

为什么要有扩展方法?就是为了在不修改源码的情况下,为某个类 增加新的方法。

u  语法:

定义静态类,并添加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);

u  注意:

1.当我们把扩展方法定义到其它程序集中时,一定要注意调用 扩展方法的环境中包含 扩展方法所在的命名空间。

如,在Extention下为String类添加一个扩展方法

然后在页面中使用时,要记得导入命名空间,否则调用不到扩展方法:

2.扩展方法需要使用特性ExtensionAttribute,当前程序中必须包含程序集ComplilerServices,否则报错如下:

注:此程序集默认在FrameWork3.5开始自动包含。

3.因为扩展方法的本质是被编译后替换成静态方法,所以 对象本身 可以为 null,但是在这个扩展方法中,如果访问了第一个参数,则会报“空指针异常”。

u  查看源码:

1.通过源码看到,在执行 string str = d.SayHi();的地方,编译后变成了 这个扩展方法通过静态类的调用方式代码。由此可见,扩展方法并没有被"扩展"到Dog类中,只不过是在编译的时候替换成了静态类里的静态方法而已。d.SayHi()就是一个语法糖!

u  思考:如果 Dog类中本身就包含 SayHi方法,那会怎么样?

但同时包含同名的 实例方法 和 扩展方法时,优先调用实例方法。

泛型委托

u  回顾通过【比较接口】方式:

让 Dog集合 根据Dog的id排序,需要写一个IComparer<Dog>接口的实现类,在类中重写 接口的 Compare方法,来返回 正整数/0/负整数。

接口:

实现类(比较器):

然后将实现类对象传入集合的Sort方法:

u  使用泛型委托 + 匿名方法实现:

List<T>集合类中包含 新的排序方法,根据 泛型委托Comparison<T> 完成比较过程。

public void Sort(Comparison<T> comparison);

看看这个Comparison<T> 泛型委托:

public delegate int Comparison<in T>(T x, T y);

修改调用的方法:

u  常用系统泛型委托:

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方法,并传入委托变量。

MVC入门之.Net语法学习的更多相关文章

  1. ASP.net MVC入门及Razor语法

    一.MVC入门: 1.MVC简介 约定大于配置 2.MVC访问流程 csthml模板(razor模板)就是简化HTML的拼接的模板,最终还是生成html给浏览器显示,不能直接访问cshtml文件. 二 ...

  2. .Net MVC 入门之Razor语法

    Razor语法 Razor是以后MVC项目中都需要用的, 所以在学MVC的基础的时候,我们的目标:要了解熟悉Razor页面的语法结构,做到灵活使用,so我们马上开始学习Razor,也请你们多评论和推荐 ...

  3. SSM(spring mvc+spring+mybatis)学习路径——2-1、spring MVC入门

    目录 2-1 Spring MVC起步 一.回顾Servlet 二.SpringMVC简介 三.搭建SpringMVC第一个案例 四.简单流程及配置 五.使用注解开发Controller 六.参数绑定 ...

  4. Spring框架学习(7)spring mvc入门

    内容源自:spring mvc入门 一.spring mvc和spring的关系 spring mvc是spring框架提供的七层体系架构中的一个层,是spring框架的一部分,是spring用于处理 ...

  5. 26、ASP.NET MVC入门到精通——后台管理区域及分离、Js压缩、css、jquery扩展

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 有好一段时间没更新博文了,最近在忙两件事:1.看书,学习中...2.为公司年会节目做准备,由于许久没有练习双截棍了,难免生疏,所以现在临时抱 ...

  6. ASP.NET MVC 入门系列教程

    ASP.NET MVC 入门系列教程 博客园ASP.NET MVC 技术专题 http://kb.cnblogs.com/zt/mvc/ 一个居于ASP.NET MVC Beta的系列入门文章,有朋友 ...

  7. 005.Getting started with ASP.NET Core MVC and Visual Studio -- 【VS开发asp.net core mvc 入门】

    Getting started with ASP.NET Core MVC and Visual Studio VS开发asp.net core mvc 入门 2017-3-7 2 分钟阅读时长 本文 ...

  8. 《java从入门到精通》学习记录

    目录 <Java从入门到精通>学习记录 3 基础的基础部分: 3 一. 常量与变量 3 1. 掌握: 3 (1) .常量与变量的声明方式: 3 (2) .变量的命名规则: 3 (3) .变 ...

  9. MVC入门教程

    MVC入门系列教程-视频版本,已入驻51CTO学院,文本+视频学效果更好哦.视频链接地址如下: 点我查看视频.另外,针对该系列教程博主提供有偿技术支持,群号:226090960,群内会针对该教程的问题 ...

随机推荐

  1. 从Lumia退役看为什么WP走向没落(从程序员与市场开发的角度,讲的真棒!)

    http://www.cnblogs.com/zhangkai2237/p/4856880.html

  2. Linux Shell逻辑运算符和表达式详解

    Shell 逻辑运算符涉及以下几种类型,只要适当选择,可以解决我们很多复杂的判断,达到事半功倍效果. 一.逻辑判断1.关于文件与目录的逻辑判断-f 常用.判断『文件』是否为普通文件,比如: if [ ...

  3. 按每k个结点反转链表

    //按每k个结点反转链表 Node* turn_k(Node* head,int n,int k) { Node* p=head; ;t<k;t++) p=p->next; //为了获取最 ...

  4. leetcode:Multiply Strings(字符串的乘法)【面试算法题】

    题目: Given two numbers represented as strings, return multiplication of the numbers as a string. Note ...

  5. 信息熵(Entropy)究竟是用来衡量什么的?

    信息熵(Entropy)究竟是用来衡量什么的? ——与Philip ZHANG商榷 思明 Philip ZHANG先生在反驳彭小明的时候,提出一个观点,他说:“ 就语言文 字来说,总体效率不是用民族主 ...

  6. 随着时间的推移:构造SDK路径错误(An error occurred while automatically activating bundle com.android.ide.eclipse.adt)

    在进行Android应用的开发过程中,有时候在配置SDK路径的时候(Windows->Preferences->Android).会出现例如以下报错:An error occurred w ...

  7. Play Framework Web开发教程(33): 结构化页面-组合使用模板

    和你编写代码相似,你编写的页面也能够由多个小的片段组合而成,这些小的片段本身也能够由更小的片段构成.这些小片段一般是能够在其他页面反复使用的:有些部分能够用在全部页面,而有些部分是某些页面特定的.本篇 ...

  8. Word文档分割总结

    Word文档分割总结 方法: 1. word创建子文件实现文件分割 2. VBA实现 3. 网上分割合并的插件软件 一. word创建子文件实现文件分割 打开需要分割的文件 >> 视图 & ...

  9. TravelCMS旅游网站系统诞生记

    本人就是一纯粹码农,没什么学历,更没什么技术,但是自认为学习能力还不错,近期有一个旅游网站系统项目正在进行中,在此以贴图记录这个项目的诞生过程,本是一个定制系统,但是不想把系统做死,以通用产品的标准来 ...

  10. 前台传来的文件通过流stream转成bytes 再把文件写入数据库 类型是blob

    //获取前台传来的文件 HttpFileCollection files = HttpContext.Current.Request.Files; Stream st = files[0].Input ...