文档章节

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

o
 osc_pn11u1x9
发布于 2018/08/06 10:00
字数 2421
阅读 12
收藏 0

精选30+云产品,助力企业轻松上云!>>>

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

一、隐式类型var

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

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

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

2、隐式类型的数组

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

3、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(“”)
{}

4、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);
    }

二、扩展方法

   使您能够向现有类型“添加”方法,而无需创建新的派生类型。

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

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

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

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

所有的扩展方法写在一个静态类中,相当于存放扩展方法的容器。

所有的扩展方法为静态方法。

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

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

三、自动实现的属性

  当属性访问器中不需要其他逻辑时,自动实现的属性声明更为简洁。

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

public int One{get;set;}

2、使用private set设置只读的自动属性,在定义此属性的类本身中还是可以初始化赋值的。

public string Name{get;private set;}

3、自动实现的属性不允许具有Attribute属性。


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

1、对象初始值设定项

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

例1:简单应用

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);
}

2、集合初始值设定项

    无需再代码中指定对该集合类的多个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指定为其中的一个元素

例3、如果集合支持读取/写入索引,可以指定索引元素。

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 可能只支持两者中的一种。

五、匿名类型

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

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

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

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

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

1、匿名类型的属性名称可以从表达式中推断出来:

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

相当于:

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

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

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"}
     }
 }

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]);

4、在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);
    }
}

5、应用

匿名类型对象的传递

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

六、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");

    }
}

1、简单应用

将λ表达式分配给委托类型,同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);
}

2、事件处理程序

当λ表达式有一个输入参数时,括号是可选的。使用空括号指定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);
}

3、创建表达式树类型

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

七、Linq表达式

1、简单应用:

检索所有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);
 }

2、嵌套成员:

检索所有城市为伦敦,且订单日期为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);
}

八、表达式树

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

1、如果操作符被声明为可以接受一个方法委托,则编译器将生成IL代码。

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

2、如果操作符被声明为可以接受一个方法委托“表达式”,则编译器将生成一个表达式树。

public  static IQueryable Where(this IQueryable source,Expression > predicate);
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
C#各版本新增加功能(系列文章)

  本系列文章主要整理并介绍 C# 各版本的新增功能。 C# 8.0 C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布,但是当前处于预览状态。预计在2019年9月正式发布。...

osc_cw9m1qtk
04/16
2
0
C#各版本

C#各版本  本系列文章主要整理并介绍 C# 各版本的新增功能。 C# 8.0 C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布,但是当前处于预览状态。预计在2019年9月正...

osc_9wny6wso
2019/09/16
4
0
C# 与 .NET Framework 对应关系

C#各版本新增加功能(系列文章)   本系列文章主要整理并介绍 C# 各版本的新增功能。 C# 8.0 C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布,但是当前处于预览...

osc_9xhruhtf
2019/09/02
4
0
C#每个版本新特性

一直都认为学习语言应该系统的进行学习,了解每一个版本的新增特性,才能在实际应用中做到有的放矢。最近发现团队中有不少人虽然用着最新的技术,但知识储备还停留在一个比较初始的状态,这样...

元歌
2019/07/03
17
0
C#3.0自动属性&匿名属性及扩展方法

前言 这一章算是看这本书最大的收获了, Lambda表达式让人用着屡试不爽, C#3.0可谓颠覆了我们的代码编写风格. 因为Lambda所需篇幅挺大, 所以先总结C#3.0智能编译器给我们带来的诸多好处, 下一...

阳光小帅
2019/11/27
15
0

没有更多内容

加载失败,请刷新页面

加载更多

强制行家更新 - Force maven update

问题: I imported my working project on other computer so it started to download dependencies. 我将工作项目导入其他计算机,因此它开始下载依赖项。 Apparently in the meantime my ......

javail
34分钟前
13
0
skywalking实现分布式系统链路追踪

一、背景 随着微服务的越来越流行,我们服务之间的调用关系就显得越来越复杂,我们急需一个APM工具来分析系统中存在的各种性能指标问题以及调用关系。目前主流的APM工具有CAT、Zipkin、Pinpo...

燚-焱
40分钟前
16
0
2020最新的Spring Boot 分布式锁的具体实现(内附代码)

前言 面试总是会被问到有没有用过分布式锁、redis 锁,大部分读者平时很少接触到,所以只能很无奈的回答 “没有”。本文通过 Spring Boot 整合 redisson 来实现分布式锁,并结合 demo 测试结...

北柠Java
46分钟前
28
0
Shiro中获取Cookie

自定义shiro的SessionIdCookie 在使用shiro的时候,曾经有段时间很苦恼,因为我cookie的sessionId经常无故被改,然后抛There is no session with id [xxxx]的异常。我们知道,当请求过来,s...

豫华商
47分钟前
9
0
JPA和Hibernate有什么区别? [关闭] - What's the difference between JPA and Hibernate? [closed]

问题: I understand that JPA 2 is a specification and Hibernate is a tool for ORM. 我知道JPA 2是一个规范,而Hibernate是ORM的工具。 Also, I understand that Hibernate has more fea......

富含淀粉
今天
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部