C#2008语言特征1---隐含类型本地变量

 

最近,微软在C#规范方面动作十分的迅速,在C#2.0规范推出不久,还没有让很多人熟悉其新的特点,很快又推出了C#3.0规范。随着新版本的推出,又增加了很多的新的特征。大家对新的特征评价不一。有的人对新特性的推出兴奋不已,感叹微软实力的雄厚以及在语言方面新思想的超前。另外一部分人认为新特性在不断的破坏完全面向对象的思想,让.Net框架下面的语言变得越来越臃肿,越来越复杂难用,这些新的特性有的甚至动摇了一些思想的根本。

究竟这些新的特征如何?还是需要程序员本身去真实的感受,也许有些特点你会发现是你梦寐以求的,也许你觉得不过如此而已。那么这些新的特征有那些呢?这些新的特征主要包含隐含类型本地变量(implicitly typed local variable declaration)、自动属性(Automatic Properties)、扩展方法(Extension Methods)、局部方法(Partial Method)、对象初始化器(Object Initializers)、匿名类型(Anonymous Type)等。

本节主要针对上面的一些特征,根据具体的实例来讲解,同时尽量解析这些新的特征的实现技术与本质。

9.1隐含类型本地变量

C#语言是一种强类型的语言,以前在声明变量的同时,必须显式指出该变量的类型,否则将会出现编译错误,从C#3.0开始,在声明一个变量的同时,可以不具体说明该变量的类型,而可以声明为var类型。

很多有经验的程序员可能一眼就认出这个“var”是JavaScript的,这个变量在JavaScript中可以保存任何数据类型的数据,相当于是一个变体类型,也就是这个类型会随着存储数据的不同而自动改变类型,但是同时也带来了程序的不安全等因素,还有最大的是性能方面的损失。微软在C#3.0中的“var”是不是跟JavaScript的中的含义相同呢?下面看一个具体的实例ImplicitlyLocalVar

namespace ImplicitlyLocalVar

{

    class Program

    {

        static void Main(string[] args)

        {

            var Iint = 3;

            var Ddouble = 5.9;

            var Ffloat = 5.6f;

            var Sstring = "我使用c#编程。";

            var IintArray = new int[3] { 4,5,6 };

            Console.WriteLine("{0}-------{1}",Iint,Iint.GetType());

            Console.WriteLine("{0}-------{1}", Ddouble, Ddouble.GetType());

            Console.WriteLine("{0}-------{1}", Ffloat, Ffloat.GetType());

            Console.WriteLine("{0}-------{1}", Sstring, Sstring.GetType());

            foreach (var temp in IintArray)

                Console.WriteLine("{0}-------{1}", temp, temp.GetType());

            Console.ReadKey();

        }

    }

}

在上面的程序中声明了很对的变量,但是没有一个变量显式的声明变量的具体类型,最后使用变量的GetType方法打印出具体的类型。程序运行的结果是:

1

 

从运行结果可以看出,每一个变量在运行是都知道自己属于那个具体的类型,而不是像JavaScript那样采用了变体类型的概念,下面在看一下使用Reflector工具反编译的代码。

9-1是反编译的代码。

2

 

9-1

从反编译以后的代码可以看出,编译器在编译代码的时候已经根据变量初始的值自动将var类型替换为具体的类型了,所以从这一点来说,c#中的varJavaScript的完全不同。

因为c#在编译代码的时候,要根据var变量的初始值来确定它的类型,所以有一定的约束规则,这些规则如下:

1)声明者必须包含一个构造者。

这个构造者必须是一个表达式。这个构造者不能够是一个对象或者构造者集合的自身,但是它可以是一个新的包含一个对象或者构造者集合的表达式。

2)在编译时刻构造者表达式的类型不能为null类型。

3)如果本地变量声明包含多种声明者,那么构造者必须都具有相同的编译时刻类型。

根据规则,下面就是一些错误的使用var的情况。

var x;  //错误,因为没有给变量初始值

var y={1,2,3}; //错误,集合不能被初始化

var z=null;  //错误,初始化的值不能是null

关键字 var 只能在本地范围内使用。换句话说,可以用这种方式去定义本地的变量,可是成员或者参数却不能。

比如用法

class VarDemo {

// 变量作为类,接口的成员变量

var k =0;

// var类型的变量不能作为方法或者函数的参数

public void InvalidUseParameter( var x ){}

// var类型的变量不能作为方法或者函数的返回值

public var InvalidUseResult() {

return 2;

}

k 的类型能从常量初始化器中推断,但是var不允许作为成员的类型。 InvalidUseResult 返回值的类型虽然可以从内部的return语句声明中推断出来,但这种用法依然是不允许的。

虽然这样简化了代码编写,但是它降低了代码的可读性。例如,您调用一个重载方法,而方法的各个版本仅是参数类型不同,阅读这代码将不清楚哪个版本的方法被调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值