C#3.0新特性:( NET Framework 3.5 与 Visual Studio 2008 )隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、匿名对象、Lambda,L...

C# 3.0 版和 Visual Studio 2008 一块儿发布于 2007 年下半年,但完整的语言功能是在 .NET Framework 3.5 版中发布的。 此版本标示着 C# 发展过程当中的重大更改。 C# 成为了真正强大的编程语言。html

1、隐式类型var

  从 Visual C# 3.0 开始,在方法范围中声明的变量能够具备隐式类型var。隐式类型能够替代任何类型,编译器自动推断类型。spring

一、var类型的局部变量必须赋予初始值,包括匿名类(初始值不能为null)。

var s = ”c#”; var name = new {name=”aa”,age=24};

二、隐式类型的数组

var a = new[]{100};//int[] a=new int[]{1,10,100}
var b = new[]{new[]{1,2,3},new[] {4,5,6}}//交错数组也可用new[]初始化,不支持隐式类型的多位数组。

三、var 只能做为局部变量使用,即只能定义在方法内或在属性get、set访问器中。还可用于foreach ,for , using语句中。

public string Name { get { var p = new Person();//正确
           return p.Name; } }
for(var i=0;i<10,i++) {} using (var file=new StreamReader(“”) {}

四、var 多数状况在匿名类型和LINQ中使用。

 string[] words = { "aa", "bb", "cc" }; var upperLower = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() }; foreach (var word in upperLower) { Console.WriteLine(word.Upper+","+ word.Lower); }

2、扩展方法

   使您可以向现有类型“添加”方法,而无需建立新的派生类型。编程

一、最多见的扩展方法是LINQ标准查询运算符。

    扩展方法向IEnumerable和IEnumerable类型添加查询功能。c#

int[] ints={10,45,15,39}; var result=ints.OrderBy(g=>g);//扩展方法是一种特殊的静态方法,但可像扩展类型上的实例方法同样进行调用。
foreach(var i in result) { Console.Write(i); }

二、对已有的类型进行扩展。

全部的扩展方法写在一个静态类中,至关于存放扩展方法的容器。api

全部的扩展方法为静态方法。数组

扩展方法的第一个参数this后跟着的类表示要扩展的类型。扩展方法第一个参数后才是真正的参数列表。app

void Main() { string s = "Hello Extension"; int i = s.WordCount(); Console.WriteLine(i.ToString()); } public static class MyExtensions //全部的扩展方法写在一个静态类中,至关于存放扩展方法的容器。
{ public static int WordCount(this String str)//this String表示要扩展的类型。扩展方法第一个参数后才是真正的参数列表
 { return str.Split(new char[] { ' ', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } }

3、自动实现的属性

  当属性访问器中不须要其余逻辑时,自动实现的属性声明更为简洁。编程语言

一、自动实现的属性必须同时声明get和set访问器。

public int One{get;set;}

二、使用private set设置只读的自动属性,在定义此属性的类自己中仍是能够初始化赋值的。

public string Name{get;private set;}

三、自动实现的属性不容许具备Attribute属性。


4、对象/集合初始值设定项

一、对象初始值设定项

  能够在建立对象时向对象的可访问字段或属性赋值,而无需显示调用构造函数。从 C# 6 开始,除了分配字段和属性外,对象初始值设定项还能够设置索引器。函数

例1:简单应用this

public class Cat { public string name { set; get; } public int age { get; set; } } void Main() { //老式
    Cat x = new Cat(); x.name = "aa"; x.age = 1; //对象初始值设定项
    Cat x1 = new Cat { name = "aa", age = 1 }; Console.Write(x1.age); }

例2:嵌套应用

class Rectangle { public Point P1 { set; get; } public Point P2 { set; get; } public Rectangle() { P1 = new Point(); P2 = new Point(); } }

void Main() { Rectangle myRec = new Rectangle { P1 = new Point() { X = 1, Y = 1 }, P2 = new Point() { X = 200, Y = 200 } }; Console.Write(myRec.P2.Y); } 

二、集合初始值设定项

    无需再代码中指定对该集合类的多个Add方法调用,编译器自动添加调用。

集合类必须实现IEumerable。

例1:

List<int> list=new List<int> {0,1,2,3};

例2:

List a = new List { new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 }, new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 } } //若是Add方法容许,能够将null指定为其中的一个元素

例三、若是集合支持读取/写入索引,能够指定索引元素。

var numbers = new Dictionary<int, string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };

注意:前面的示例生成调用 Item[TKey] 以设置值的代码。 从 C# 6 开始,可使用如下语法初始化字典和其余关联容器。  它使用具备多个值的对象,此初始值设定项示例调用 Add(TKey, TValue),将这三个项添加到字典中。

var moreNumbers = new Dictionary<int, string> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } };

因为编译器生成的方法调用不一样,这两种初始化关联集合的不一样方法的行为略有不一样。 这两种变量都适用于 Dictionary 类。 其余类型根据它们的公共 API 可能只支持二者中的一种。

5、匿名类型

匿名类型是编译器动态建立的一个类,用于存储一组值。

要建立匿名类型,请使用new关键字和对象初始化器,指定类型将包含的属性和值。

能够将一组只读属性封装到单个对象中,无需首先定义一个类型。匿名类型只能用于定义它的方法中。

匿名类型由一个或多个公共只读属性组成。成员不能用null赋初值。若是多个匿名类型有相同数量和种类的属性,编译器将视为相同的类型,生成多个实例。

var noName = new { name = "a",
age = 1 }; Console.Write(noName.name);

一、匿名类型的属性名称能够从表达式中推断出来:

int Age = 3; var person = new { Name = "Jack", Age, Age.ToString().Length };

至关于:

var person = new { Name = "Jack", Age = Age, Length = Age.ToString().Length };

二、由匿名类型构成的数组

var anonArray = new[] { new { name = "apple", diam = 4 },
new { name = "grape", diam = 1 }};

生成匿名类型数组

var result = new { pages = 10, Users = from mo in list select new { id = mo.UserId, name = mo.Nick } };

能够生成:

var result = new { pages = 10, users = new[]{  new{id=1,name="2"}  new{id=2,name="3"} } }

三、由匿名类型构成的列表和字典

var a1 = new List<dynamic>() { new { X = 100, Y = 200 }, new { X = 300, Y = 400} }; Console.Write(a1[1].X); var moreNumbers = new Dictionary<dynamic, dynamic> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } }; Console.Write(moreNumbers[19]);

四、在Linq 中使用

匿名类型一般用在查询表达式的 Select 子句中,以便返回原序列中每一个对象的属性子集(Linq 中使用的比较多)。

class MyClass { public string Name { set; get; } public int Number { set; get; } } void Main() { MyClass[] list = new MyClass[12]; var varbj = from obj in list select new { obj.Name,
ID=obj.Number};
    foreach (var v in varbj) { Console.Writ(v.Name, v.ID); } }

五、应用

匿名类型对象的传递

void Main() { //匿名类型
    var news = new { title = "冰红茶", day = "2019-4-10", author = "康师傅" }; ShowInfo(news); } static void ShowInfo<T>(T news) { dynamic d = news; Console.WriteLine(d.title); Console.WriteLine(d.day); Console.WriteLine(d.author); }
用匿名类型填充数组,并计算总年龄
var family = new[]                         //使用隐式类型的数组初始化程序
 { new { Name = "Holly", Age = 37 },      //同一个匿名类型连用5次
            new { Name = "Jon", Age = 36 }, new { Name = "Tom", Age = 9 }, new { Name = "Robin", Age = 6 }, new { Name = "William", Age = 6 } }; int totalAge = 0; foreach (var person in family)  //totalAge累加 对每一个人使用
{ totalAge += person.Age; } Console.WriteLine("Total age: {0}", totalAge);

6、Lambda表示式

(详细见https://www.cnblogs.com/springsnow/p/9441946.html

  是一个匿名函数,它能够包含表达式和语句,可用于建立委托或表达式目录树类型。

从 C# 1.0 - 3.0委托示例

///  /// C# 1.0 - 3.0 委托的发展过程 /// 
public class DelegateEvlove { //方法1 定义委托
    public delegate void TestDelegate(string s); static void ConsoleStr(string s) { Console.WriteLine(s); } public static void Main(string[] args) { //方法1 实例化委托
        TestDelegate iDelegate = new TestDelegate(ConsoleStr); //方法1 调用委托
        iDelegate("1 instance delgate"); //方法2 匿名委托
        TestDelegate aDelegate = delegate (string s) { Console.WriteLine(s); }; aDelegate("2 anonymous delegate"); //方法3 lambda 表达式
        TestDelegate lDelegate = (s) => { Console.WriteLine(s); }; lDelegate("3 lambda delegate"); } }

一、简单应用

将λ表达式分配给委托类型,同delegate(int x){retun x*x}(匿名函数)

delegate int del(int i); void Main() { del myDel = x => x * x;//或 x=>{return x*x };
    int j = myDel(5); Console.Write(j); }

二、事件处理程序

当λ表达式有一个输入参数时,括号是可选的。使用空括号指定0个输入参数。也能够显示指定参数类型

public static event EventHandler myEvent; void Main() { myEvent += (s, e) => { Console.Write(s); }; //即myEvent += delegate(object s,EventArgs e) => { Console.Write(s); }; myEvent(this, null); }

三、建立表达式树类型

using System.Linq.Expressions; Expression = x=>x*x;

7、Linq表达式

一、简单应用:

检索全部Sex为false的人,查询结果放到results变量中,results变量与数组persons类型相同

using System.Linq; var persons = new[] { new { Name = "var", Sex = false },
new { Name = "var2", Sex = false } }; var results = from p in persons//
where p.Sex == false
              select p;
 foreach (var person in results) { Console.Write(person.Name); }

二、嵌套成员:

检索全部城市为伦敦,且订单日期为2018年之后的全部记录,查询结果是一个匿名类型的数组。

var customers = new[] { new { Name = "var",City="China" ,Orders  = new []{new{OrderNO=0,OrderDate=new DateTime(2017,1,1)}, new{OrderNO=1,OrderDate=new DateTime(2018,1,1)}, }}, new { Name = "Vicky",City="London" ,Orders  = new []{new{OrderNO=2,OrderDate=new DateTime(2019,9,1)}, new{OrderNO=3,OrderDate=new DateTime(2018,1,1)}, } } }; var someCustomers = from c in customers where c.City == "London" from o in c.Orders where o.OrderDate.Year > 2018 select new { c.Name, o.OrderNO }; foreach (var customer in someCustomers) { Console.Write(customer.Name + customer.OrderNO); }

8、表达式树

一种有效的数据表达方式,以树的形式显示λ表达式。这些全部数据表达方式能够同时进行编译。

一、若是操做符被声明为能够接受一个方法委托,则编译器将生成IL代码。

public  static IQueryable Where(this IEnumerable source,Func predicate);

二、若是操做符被声明为能够接受一个方法委托“表达式”,则编译器将生成一个表达式树。

public  static IQueryable Where(this IQueryable source,Expression > predicate);
相关文章
相关标签/搜索