一、C# 3.0,对应.NET 3.0/3.5,对应VS 2008,新特性:隐式类型的部变量、对象集合初始化、查询表达式、表达式树、分部类和方法、AJAX、LINQ、Entity Framework、ADO.NET、类型推断(var)、自动属性、匿名类型、扩展方法、Lambda表达式
1、类型推断
就是var关键字,和弱类型的var(如js)不一样。js的var,定义了可以随便转换,从字符串转成数字之类。C#的var,只是语法糖,实际还是一样,如var i = 1 相当于 int i = 1(平时用Resharper习惯把var识别出来,这样容易有智能提示,也知道具体是什么类型)
2、扩展方法
类似js的原型。主要就是参数加上this,下面例子相当于把StrToInt32("abc")变成"abc".StrToInt32
public static int StrToInt32(this string s) { return Int32.Parse(s); }
3、自动属性
public int X { get; set; }
属性不用那么麻烦又是定义私有同名变量,又是取值赋值了,直接{get;set;}
4、集合初始化
Point p = new Point { X = 23, T =2}
在初始化时就可以进行赋值
5、Labda表达式
有返回值:(int a,int b) => { return a>b; }
改进1:(a,b) => { return a>b; } //类型可以系统推断
改进2:(a,b) => a>b; //可以省略大括号和return,Linq里经常 .Where(x=>x.Id=="abc")
改进3:() => 1>0 //没有参数时可以只用括号(这个没测过写法对不对,应该是可以的)
无返回值(int a,int b) => { Console.Write(a+b); }
改进1:(a,b)=>{ Console.Write(a+b); }
改进2:()=>{ Console.Write("test"); } //经常用到 ()=>{}这种形式
6、匿名类型
var a = { name="张三", age=10 }
在js里经常有用var a={ name:"张三", age:10 }
7、查询表达式/Linq/EF
这几个配合在一起用,可以对数据库、集合等进行增删改查
from c in coords where x == 1 select (c) coords.where(c => c.x == 1)
8、Ado.Net
使用原生Sql语句操作数据库,可以连接各种数据库。一般公司都封装好了SqlHelper或AdoHelper之类,直接用Command的三大对象,传Sql字符串进去即可,不可能每次都写完整的Ado.Net的
Connection类:一般把连接参数写在web.config里
Command对象:
ExecuteNonQuery:执行语句,返回影响条数
ExecuteReader:只读向前游标,每次一行,读完为止。目前项目主要就用这个,分页、转json等,都是直接用DataReader
ExecuteScalar:返回结果的第一行第一列,是个object,不是string,要转换一下类型,而且不要用.ToString(),要用Convert.ToString(),不然碰到null时.ToString()会报错
DataReader类:见ExecuteReader
DataSet对象:没用过,项目里都封装好了
DataSet里面可以包含多个DataTable,DataTable中有多个DataColumn和多个DataRow
DataSet则是将数据一次性加载在内存中.抛弃数据库连接..读取完毕即放弃数据库连接..因为DataSet将数据全部加载在内存中.所以比较消耗内存...但是确比DataReader要灵活..可以动态的添加行,列,数据.对数据库进行回传更新操作
DataAdapter类:没用过,项目里都封装好了
DataAdapter 填充(fill)DataSet对象。DataAadapter包含对连接对象以及当对数据库进行读取或者写入的时候自动的打开或者关闭连接的引用。
DataTable类:把数据读到内存里,像一个表格一样,可以对该“表格”进行遍历,取出想要的数据
9、Ajax
Asp.Net支持Ajax,有UpdatePanel控件,但我没用过,都是直接在js里用jquery操作ajax
二、C# 4.0,对应.NET 4.0,对应VS 2010,新特性:dynamic、动态绑定、可选(默认)参数、命名参数、泛型的协变和逆变、互操作性
1、dynamic
var/object/dynamic,三者容易搞混
var a=1; //此时编译器就已经推断出a是int型了,相当于int a=1; Console.Write( a+1 ); object a=1; Console.Write( (int) a+1 ) //object要类型转换 dynamic a=1; //在编译时并不知道a是int型,只有在执行时才判断出a为int Console.Write(a+1) //不用类型转换 dynamic a = "A"; a++; //编译时不会报错,因为dynamic编译时并不去推断类型,在执行时会报错
2、可选(默认)参数
private void Test(string a, int b= 0, int c= 1)
可以Test("a")这样调用,不传的参数会有默认值
但要注意,默认值只能放在最后或者一直延续到最后,不然就不知道中间跳过还是没跳过了
3、命名参数
private void Test(string a, int b)
可以Test(b:1, a:"a")这样调用,不用按顺序
三、C# 5.0,对应.NET 4.5,对应VS 2012,新特性:异步编程(async/await)、调用方信息、带参数的泛型构造函数、扩展属性、【支持null类型运算、case支持表达式】?
1、异步编程(async/await)
因为await 只能wait Task,并且await 只能用在async 标记的方法中,async 关键字表明这是个异步方法。
static async void DownloadStringAsync2(Uri uri) { var webClient = new WebClient(); var result = await webClient.DownloadStringTaskAsync(uri); Console.WriteLine(result); }
当一个async方法,且内部包含await关键字,它就会在编译的时候成为一个异步方法,如果没有await关键字,则它将只会被当成一个同步方法来执行。
public async Task<int> SumPageSizesAsync3(IListuris) { int total = 0; foreach (var uri in uris) { WebClient webClient=new WebClient(); var data = await webClient.DownloadDataTaskAsync(uri); total += data.Length; } return total; }
2、调用方信息
public void TraceMessage(string message, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { Trace.WriteLine("message: " + message); Trace.WriteLine("member name: " + memberName); Trace.WriteLine("source file path: " + sourceFilePath); Trace.WriteLine("source line number: " + sourceLineNumber); }
就是可以记录当前运行到哪了,像下了断点一样,可以记录下来。
3、可空类型计算(查了下应该不是什么5.0新特性,很早就有了,也没找到可空类型的什么新特性。网上资料全是转来转去的,微软官网上找不到)
int? value = 1 相当于 Nullable
int? x = null; int? y = x + 1; int? z = x ?? +1; Console.WriteLine(y); //null Console.WriteLine(z); //1 Console.ReadKey();
??表示判断是否null,如果空就使用后面的,非null就使用自身。像int i = j ?? 1; //如果j是null就会取1
4、case表达式,本以为switch里面可以判断表达式或方法返回值了,试了一下不行,这说法不知哪来的,网上转来转去都是同一篇。最多只能枚举,其实也还是常量
DayOfWeek day = DayOfWeek.Monday; switch(day){ case DayOfWeek.Monday: break; case DayOfWeek.Tuesday: break; }