zoukankan      html  css  js  c++  java
  • C# 3进化的数据访问之智能的编译器

    C# 3进化的数据访问之智能的编译器

    C# 2的两个重要特性要求CLR做出了相应的改变,但是C# 3引入的特性并没有改变CLR,只是框架库扩充了LINQ、基类库引入了几个新特性。C# 3的所有特性都是智能的编译器帮你做了更多的事。

    自动实现的属性

    公开可见的静态成员通常应该是线程安全的,但是编译器帮不了你,需要自己加锁:

    1. private static int InstanceCounter{ get; set; }
    2. private static readonly object counterLock = new object();//锁

    然后在访问静态成员时使用锁。使用Innerlocked类可能会更好。

    隐式类型的局部变量——var

    C# 1的类型系统是静态、显式和安全的。在C# 3中静态和安全仍然成立,大多数时候也是显式类型,只有在使用var来要求编译器帮你推断局部变量的类型时是隐式的。

    隐式类型的限制

    隐式类型只能在声明变量是局部变量时(不是静态字段和实例字段),并且在申明同时被初始化,而且初始化的表达式也不能是方法组、匿名方法或Lambda表达式,也不能是null。事实上,最常见的应用是用方法调用的结果来初始化隐式类型的变量。次常用的就是在using、for、foreach语句的开头部分声明局部变量时使用。

    隐式类型的优缺点

    读代码时,相同的长类型名称(使用泛型时很常见)在一行没有必要出现两次时,可以选择使用隐式类型。
    隐式类型将读者的注意力从变量的声明转移到变量的使用上。所以对可读性有些优势。但是这主要取决于能否通过查看初始化表达式来轻松推断出返回的类型。

    简化的初始化——对象初始化器

    大多数语言只有两种方式,带参数列表的构造函数,或者是先构造对象,然后用属性设置来手动初始化它。如果需要一次构造集合时,由于无法使用单一的表达式来初始化对象,让人非常恼火。
    简单的初始化器:Person tom = new Person { Name = "Tom", Age = 9 }
    为嵌入对象设置属性:

    1. Person tom = new Person("Tom")
    2. {
    3. Age = 9,
    4. Home = { Country= "UK", Town = "Reading"}
    5. };

    集合初始化程序:

    左侧是C# 2,右侧是等价的C# 3的代码。
    多种初始化器的混合使用:

    隐式类型的数组

    C# 1和C# 2中可以这么写string[] names = { "Holly", "Jon", "Tom", "Robin", "William" };
    这种用法用在方法参数中时,必须显式地告诉编译器初始化的数组类型是什么,
    MyMethod(new string[] { "Holly", "Jon", "Tom", "Robin", "William" });
    在C# 3中,上例的string[]可以省略了:
    MyMethod(new[] { "Holly", "Jon", "Tom", "Robin", "William" })
    注意:只有表达式的类型才会成为一个候选的数组类型。
    C# 3的这个特性主要用在不知道数组元素类型的时候。怎么会出现这种奇怪的现象呢?——答案是匿名类型。

    匿名类型

    上述的隐式类型、对象和集合初始化器组合起来可以服务于一个更高的目标——匿名类型。匿名类型又服务于一个还要高的目标——LINQ。

    1. 匿名类型示例

      这个示例中只会出现一个匿名类型,因为它们的属性名称,数量,类型都是一样的,所以编译器认为是同一个类型。如果有不一样的地方,编译器对数组做类型推断将会失败。

    2. 匿名类型的成员
      匿名类型是由编译器创建并包含到最终程序集中,CLR把它们看做普通的类型,因为它们真的只是普通类型——一个获取所有初始值的构造函数(顺序与你们对象初始化程序中的顺序一样),一些公有的只读属性以及相应的私有字段,一些继承自object类的普通方法。

    3. 投影初始化程序
      new { Name = person.Name, IsAdult = (person.Age >= 18) }
      C# 3提供了一种简化的语法:
      new { person.Name, IsAdult = (person.Age >= 18) }
      规则是如果不指定属性名称,只指定用于求值的表达式,那么就会用表达式的最后部分作为名称(必须是一个简单字段或属性),这就是投影初始化程序。它在LINQ将获得广泛的使用——返回集合中的部分属性值。

    4. 重点何在

      为了避免过度的数据积累,引入了匿名类型,匿名类型用于对一种需要进行裁剪的数据进行封装,避免了手动编写重复代码。总之,匿名类型允许你只保留特定情况下的数据,针对这种情况进行裁剪而无需每次都重复地写一个新类型。

    总结

    上述特性,都能将开放人员从繁琐的编码中解脱出来。





  • 相关阅读:
    了解JVM原理
    封装JS
    “==”和Equals的区别
    SpringMVC请求RequestMapping() 请求乱码
    博客25周
    博客24周
    博客23周
    博客22周
    博客第21周
    博客第21周
  • 原文地址:https://www.cnblogs.com/qianzi067/p/6113689.html
Copyright © 2011-2022 走看看