浅谈C#中的常量、类型推断和作用域

一、常量
常量是其值在使用过程中不会发生变化的变量。在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量:

const int a=100;//a的值将不可以改变

常量的特征:

1.常量必须在声明时初始化。指定了其值以后,就不能再修改了。
2.常量的值必须能在编译时用于计算。因此不能从一个变量中提取的值来初始化常量。如果需要这么做,应该使用只读字段。
3.常量总是静态的,但注意,不必在常量的声明中包含修饰符static。(实际上,不允许)
在程序中使用常量至少有3个好处:

1.常量用易于理解的清楚的名称替代了含义不明确的数字或者字符串,使得程序更加易于阅读。
2.常量使程序更容易修改。例如在C#程序中有一个SalesTax常量,该常量的值为6%。如果以后销售税率发生变化,把新值赋给这个常量,就可以修改所有的税款计算结果,而不必查找整个程序,修改税率为0.06的每个项。
3.常量更容易避免程序出现错误。如果要把另一个值赋给程序中的一个常量,而该常量已经有了一个值,编译器就会报告错误。
如以下程序:

代码如下:

namespace Test
{
    class ScopeTest
    {
        static int j=20;
        const string time= DateTime.Now.ToString();
        public static void Main()
        {
            int j=30;
            Console.WriteLine(j);
            return;
        }
    }
}

编译后产生错误:

error CS0133:指派给“Test.ScopeTest.time”的表达式必须是常量。

对于以上代码中的time,如果需要的话,可以为其赋于readonly属性。

常量和只读其实都是只能访问不能修改的。但是他们的赋值时机不太一样,一般常量在编译的时候已经确定并赋予其常量值。而只读其实是一个变量他在运行时需要动态装载的时候才会给他赋予一个值,而这个值一旦赋予就不能再更改了。

二、类型推断
类型推断使用var关键字。声明变量的语法有些变化。编译器可以根据变量的初始化值“推断”变量的类型,例如:

int someNumber=0;

就变成

var someNumber=0;

即使someNumber从来没有声明为int,编译器也可以确定,只要someNumber在其作用域内,就是一个int。编译后,上面两个语句是等价的。

下面是另外一个例子:

代码如下:

namespace Test
{
     class Program
     {
         static void Main(string[] args)
          {
               var name ="Bugs Bunny";
               var age=25;
               var isRabbit=true;

Type nameType=name.GetType();
               Type ageType=age.GetType();
               Type isRabbitType=isRabbit.GetType();

Console.WriteLine("name is type "+nameType.ToString());
               Console.WriteLine("age is type "+ageType.ToString());
               Console.WriteLine("isRabbit is type"+isRabbitType.ToString());
               Console.ReadKey();
    }
   }
}

编译运行程序:(如何编译程序请参照C#入门篇)

name is type System.String

age is type System.Int32

isRabbit is type System.Boolean

使用var定义变量是需要一些规则的。变量必须初始化。否则,编译器就没有推断变量类型的依据。初始化器不能为空,且必须放在表达始中。不能把初始化器设置为一个对象,除非在初始化器中创建一个新对象。

三、变量的作用域
变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域有一下规则:

1.只要类在某个作用域内,其字段也在该作用域内
2.局部变量存在于声明该变量的块语句或方法结束的封闭花括号之前的作用域内。
3.在for、while或类似语句中声明的局部变量存在与该循环体内
大型程序的不同部分为不同的变量提供相同的变量名很常见。只要变量的作用域是程序的不同部分,就不会有问题。也不会产生模糊。但要注意,同名的局部变量不能在同一作用域内声明两次,所以如下代码是不能使用的:

int x=20;

int x=30;

再来看如下例子:

代码如下:

using System;
namespace jb51
{
   pulic static int main()
   {
       For(int i=0;i<10;i++)
       {
           Console.writeLie(i);
       }
       For(int i=0;i>=10;i—
       {
           Console.WriteLine(i);
    }
   }
}

这段代码需要引起我们的注意。i出现了两次,但是他们都是相对于循环体的变量。

另一个例子:

代码如下:

public static int Main()
{
  int j=20;
  for(int i=0;i<10;i++)
  {
     int j=30;//错误
    Console.WriteLine(j+i);
  }
  return 0;
}

这里会发生错误,因为变量j是在for循环开始前定义的,在执行for循环时应处于其作用域内,在Main方法执行后,变量j才超出作用域,第二个j(不合法)则在循环的作用域内,在作用域嵌套在Main方法的作用域内,编译器无法区别这两个变量。

字段或局部变量的作用域冲突:在某些情况下,可以区分名称相同(尽管其完全限定的名称不同)、作用域项目的两个标识。此时编译器允许声明第二个变量。原因是C#在变量之间有一个基本的区分,它把声明为类型级的变量字段看作字段,而把在方法中声明的变量看作局部变量。

(0)

相关推荐

  • C#之CLR内存字符串常量池(string)

    C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且String str=new String("HelloWorld")这样的重装也说没有的. 我们先来看一个方法: class Program { static void Main(string[] args) { String s = "HelloWorld"; Console.WriteLine(s); } } 然后我们用ildasm.exe工具把它生成IL语言来看一看它里面是怎么玩的: .met

  • c#只读字段和常量的区别,以及静态构造函数的使用实例

    复制代码 代码如下: using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace ConsoleApplication1{    /// <summary>    /// 作者:it小金    /// 功能:c#只读字段和常量的区别,以及静态构造函数的使用    /// </summary>    class Program    {        stat

  • C# 基础入门--常量

    常量,顾名思义,就是"不会改变的量". 我们平时书写的数字(比如12.85).字符(比如'F').字符串(比如"谢谢"),它们都属于"字面常量". 有一些常量既重要又容易出错,比如圆周率π的值为3.1415926......,所以,我们常常会使用自定义常量.如: namespace Test { class Program { static void Main(string[] args) { const double PI = 3.141592

  • C# 定义常量 两种实现方法

    在C#中定义常量的方式有两种,一种叫做静态常量(Compile-time constant),另一种叫做动态常量(Runtime constant).前者用"const"来定义,后者用"readonly"来定义. 对于静态常量(Compile-time constant),它的书写方式如下: public const int MAX_VALUE = 10; 为什么称它为静态常量呢,因为如上声明可以按照如下理解(注意:如下书写是错误的,会出编译错误,这里只是为了方便说

  • 解析C#中的常量及如何在C#编程中定义常量

    常量是在编译时已知并在程序的生存期内不发生更改的不可变值.常量使用 const 修饰符进行声明.只有 C# 内置类型(System.Object 除外)可以声明为 const. 用户定义的类型(包括类.结构和数组)不能为 const.请使用 readonly 修饰符创建在运行时初始化一次即不可再更改的类.结构或数组. C# 不支持 const 方法.属性或事件. 可以使用枚举类型为整数内置类型(例如 int.uint.long 等等)定义命名常量. 常量必须在声明时初始化.例如: class C

  • C#中常量和只读变量的区别小结

    常量和只读变量有以下区别: 1.常量必须在声明时就被初始化,指定了值后就不能修改了.只读字段可以在声明时被初始化,也可以在构造函数中指定初始化的值,在构造以后值就不能修改. 2.常量是静态的,而只读字段可以是静态和动态的 3.Const可以用在字段和局部变量,readonly只可以修饰字段

  • c# 常量和字段

    它的值是在编译时确定的.编译器将常量保存到程序集的元数据中,所有只能是编译器认识的基元类型作为常量. 常量被看成类的一部分,是看出静态成员. 代码引用一个常量符号,会在定义常量的元数据中查找该符号,提取之,并嵌入代码,生成的IL中是值本身. 在c#中使用的是const关键字. 字段:已一种数据成员,可以容纳任何的数据类型,不仅仅想常量一样只能存储基元类型. CLR支持类型字段和实例字段 类型字段:用于容纳字段数据的动态内存是在类型对象中分配的, 而类对象是在类型加载到一个AppDomain中创建

  • 浅谈python中的数字类型与处理工具

    python中的数字类型工具 python中为更高级的工作提供很多高级数字编程支持和对象,其中数字类型的完整工具包括: 1.整数与浮点型, 2.复数, 3.固定精度十进制数, 4.有理分数, 5.集合, 6.布尔类型 7.无穷的整数精度 8.各种数字内置函数及模块. 基本数字类型 python中提供了两种基本类型:整数(正整数金额负整数)和浮点数(注:带有小数部分的数字),其中python中我们可以使用多种进制的整数.并且整数可以用有无穷精度. 整数的表现形式以十进制数字字符串写法出现,浮点数带

  • 浅谈C#中的常量、类型推断和作用域

    一.常量常量是其值在使用过程中不会发生变化的变量.在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量: const int a=100;//a的值将不可以改变 常量的特征: 1.常量必须在声明时初始化.指定了其值以后,就不能再修改了.2.常量的值必须能在编译时用于计算.因此不能从一个变量中提取的值来初始化常量.如果需要这么做,应该使用只读字段.3.常量总是静态的,但注意,不必在常量的声明中包含修饰符static.(实际上,不允许)在程序中使用常量至少有3个好处: 1

  • 浅谈C#中的值类型和引用类型

    一.基本概念 C#只有两种数据类型:值类型和引用类型 值类型在线程栈分配空间,引用类型在托管堆分配空间 值类型转为引用类型称成为装箱,引用类型转为值类型称为拆箱 以下是值类型和引用类型对照表 从上图可以简单看出:string,Object,数组,class是引用类型,简单类型,枚举,结构是值类型. 二.代码展示 定义一个类和结构调用赋值 内存分配情况如下图: 从这张图可以看出,class实例化出来的对象,指向了内存堆中分配的空间:truct实例化出来的对象,是在内存栈中分配. 修改代码如下: 内

  • 浅谈C++中的string 类型占几个字节

    在C语言中我们操作字符串肯定用到的是指针或者数组,这样相对来说对字符串的处理还是比较麻烦的,好在C++中提供了 string 类型的支持,让我们在处理字符串时方便了许多. 首先,我写了一段测试代码,如下所示: 复制代码 代码如下: #include <iostream>using namespace std; int main(void){ string str_test1; string str_test2 = "Hello World"; int value1, val

  • 浅谈javascript中基本包装类型

    为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean.Number和String.这些类型与本章介绍的其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为.实际上,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据.如下例子: 复制代码 代码如下: var s1="some text"; var s2=s1.substring(2); 这个例子中的变量s1包含一个字符串,字符串当然是

  • 浅谈ECMAScript 中的Array类型

    前言 Array 类型是除了 Object 类型之外又是一个特别经常用的一个类型了,当然数组在其他的语言中都是不可缺少的属性,我们都知道不管 js 还是其他类的语言的数组都是数据的有序列表,但是在 javaScript 中的数组是有一定的区别的,具体的区别就是: js 中的数组保存的数据可以是任何类型的数据,比如,我可以在第一个位置来保存数字,第二个位置保存字符串,第三和第四保存一个对象都完全OK,同时我还可以非常方便的操作数组的大小,添加新数据长度也会自动增长,动态调整什么的都是没有任何问题滴

  • 浅谈java中的声明常量为什么要用static修饰

    今天定义一个类常量,想着也只有这个类可以用到,就没用static关键字修饰.结果sonar代码检查提示: Rename this field "PERSON_TYPE_USER" to match the regular expression '^[a-z][a-zA-Z0-9]*$'. 我一想我这是正确的命名规范啊,于是百度一搜这提示,发现前面加个static关键字修饰就可以了. 那么问题来了,我就当前类要使用,不需要设置成全局常量也可以,用static修饰常量有什么好处? 好处就是

  • 浅谈python中的变量默认是什么类型

    1.type(变量名),输出的结果就是变量的类型: 例如 >>> type(6) <type 'int'> 2.在Python里面变量在声明时,不需要指定变量的类型,变量的类型是动态指定的:>>> x=5 >>> type(x) <type 'int'> >>> x="wang" >>> type(x) <type 'str'> 3.也就是说变量的类型,根据给出

  • 浅谈MySQL中float、double、decimal三个浮点类型的区别与总结

    下表中规划了每个浮点类型的存储大小和范围: 类型 大小 范围(有符号) 范围(无符号) 用途 ==float== 4 bytes (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度 浮点数值 ==double== 8 bytes (-1.797 693 134 862 315 7 E

  • 浅谈mybatis中SQL语句给boolean类型赋值问题

    我就废话不多说了,大家还是直接看代码吧~ <select id="getBiTree" parameterType="String" resultMap="MenuVoListMap"> SELECT m.menu_id , m.parent_id , m.`name` , 1 opens FROM menu m WHERE m.is_valid = 1 AND (m.type = 0 or m.type = 1) and m.men

随机推荐