[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型-创新互联

引言

站在用户的角度思考问题,与客户深入沟通,找到集美网站设计与集美网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计、成都做网站、企业官网、英文网站、手机端网站、网站推广、空间域名、虚拟主机、企业邮箱。业务覆盖集美地区。

经过前面专题的介绍,大家应该对C# 1和C# 2中的特性有了进一步的理解了吧,现在终于迎来我们期待已久的C# 3中特性,C# 中Lambda表达式和Linq的提出相当于彻底改变我们之前的编码风格了,刚开始接触它们,一些初学者肯定会觉得很难理解,但是我相信,只要多多研究下并且弄明白之后你肯定会爱上C# 3中的所有特性的,因为我自己就是这么过来的,在去年的这个时候,我看到Lambda表达式和Linq的时候觉得很难理解,而且觉得很奇怪的(因为之前都是用C# 3之前的特性去写代码的,虽然C# 3中的特性已经出来很久了,但是自己却写的很少,也没有怎么去研究,所以就觉得很奇怪,有一种感觉就是——怎么还可以这样写的吗?),经过这段时间对C# 语言系统的学习之后,才发现新的特性都是建立在以前特性的基础上的,只是现在编译器去帮助我们解析C# 3中提出的特性,所以对于编译器而言,用C# 3.0中的特性编写的代码和C# 2.0中编写的代码是一样的。从这个专题开始,将会为大家介绍C# 3 中的特性,本专题就介绍下C# 3中提出来的一些基础特性,这些特性也是Lambda表达式和Linq的基础。

一、自动实现的属性

当我们在类中定义的属性不需要一些额外的验证时,此时我们可以使用自动实现的属性使属性的定义更加简洁,对于C# 3中自动实现的属性,编译器编译时会创建一个私有的匿名的字段,该字段只能通过属性的get和set访问器进行访问。下面就看一个C#3中自动实现的属性的例子:

  1. ///  
  2.     /// 自定义类 
  3.     ///  
  4.     public class Person 
  5.     { 
  6.         // C# 3之前我们定义属性时,一般会像下面这样去定义 
  7.         // 首先会先定义私有字段,再定义属性来对字段进行访问 
  8.         //private string _name; 
  9.         //public string Name 
  10.         //{ 
  11.         //    get { return _name; } 
  12.         //    set { _name = value; } 
  13.         //} 
  14.  
  15.         // C# 3之后有自动实现的属性之后 
  16.         // 对于不需要额外验证的属性,就可以用自动实现的属性对属性的定义进行简化 
  17.         // 不再需要额外定义一个私有字段了, 
  18.         // 不定义私有字段并不是此时没有了私有字段,只是编译器帮我们生成一个匿名的私有字段,不需要我们在代码中写出 
  19.         // 减少我们书写的代码 
  20.         // 下面就是用自动实现的属性来定义的一个属性,其效果等效于上面属性的定义,不过比之前更加简洁了 
  21.  
  22.         ///  
  23.         ///  姓名 
  24.         ///  
  25.         public string Name { get; set; } 
  26.  
  27.         ///  
  28.         /// 年龄 
  29.         ///  
  30.         public int Age { get; private set; } 
  31.  
  32.         ///  
  33.         ///  自定义构造函数 
  34.         ///  
  35.         ///  
  36.         public Person(string name) 
  37.         { 
  38.             Name = name; 
  39.         } 
  40.     } 

有些人会问——你怎么知道编译器会帮我们生成一个匿名的私有字段的呢?对于这点当然通过反射工具来查看经过编译器编译之后的代码了,下面是用Reflector工具查看的一张截图:

[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型

如果在结构体中使用自动属性时,则所有构造函数都需要显式地调用无参构造函数this(),否则,就会出现编译时错误,因为只有显式调用无参构造函数this(),编译器才知道所有字段都被赋值了。下面是一段测试代码:

  1. ///  
  2.     ///  在结构体使用自动属性 
  3.     ///  
  4.     public struct TestPerson 
  5.     { 
  6.         // 自动属性 
  7.         public string Name { get; set; } 
  8.  
  9.         // 在结构中所有构造函数都需要显示地调用无参数构造函数this(), 
  10.         // 否则会出现编译错误 
  11.         // 只有调用了无参数构造函数,编译器才知道所有字段都被赋值了 
  12.         public TestPerson(string name) 
  13.             //: this() 
  14.         { 
  15.             this.Name = name; 
  16.         } 
  17.     } 

把this()注释掉后就会出现编译时错误,如下图:

[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型

二、隐式类型

用关键字var定义的变量则该变量就是为隐式类型,var 关键字告诉编译器根据变量的值类推断变量的类型。所以对于编译器而言,隐式类型同样也是显式的,同样具有一个显式的类型。

2.1 隐式类型的局部变量

用var 关键字来声明局部变量,下面一段演示代码:

  1. static void Main(string[] args) 
  2.         {  
  3.             // 用var声明局部变量 
  4.         var stringvariable = "learning hard"; 
  5.             stringvariable = 2; 
  6.          } 

为什么说用var定义的变量对于编译器来说还是具有显式类型呢?在Visual studio中,将鼠标放在var部分的时候就可以看到编译器为变量推断的类型。并且变量仍然是静态类型,只是我们在代码中没有写出类型的名称而已,这个工作交给编译器根据变量的值去推断出变量的类型,为了证明变量时静态类型,当我们把2赋给变量stringvariable时就会出现编译时错误,然而在其他动态语言中,这样的赋值是可以编译通过,所以用var声明的变量仍然还是静态类型,只是我们在代码中没有写出来而已。下面是证明上面两点的截图:

[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型

然而使用隐式类型时有一些限制,具体限制有:

  • 被声明的变量是一个局部变量,不能为字段(包括静态字段和实例字段)
  • 变量在声明时必须被初始化(因为编译器要根据变量的赋值来推断变量的类型,如果没有被初始化则编译器就无法推断出变量类型了, 然而C#是静态语言则必须在定义变量时指定变量的类型,所以此时变量不知道什么类型,就会出现编译时错误)
  • 变量的初始化不能初始化为一个方法组,也不能为一个匿名函数(前提是不进行强制类型转化的匿名函数)
  • 变量不能初始化为null(因为null可以隐式转化为任何引用类型或可空类型,所以编译器不能推断出该变量到底应该为什么类型)
  • 不能用一个正在声明的变量来初始化隐式类型 (如不能这样来声明隐式类型
    // 不能用一个未赋值的变量来初始化隐私类型   // 如果变量s被初始化了就可以了   string s;    var stringvariable = s;

    创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


    新闻名称:[C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型-创新互联
    文章网址:http://scyanting.com/article/dppoip.html