C#中的常量、类型推断和作用域
一、常量
常量是其值在使用过程中不会发生变化的变量。在声明和初始化变量时,在变量前面家关键字const,就可以把该变量指定为一个常量:
const int a=100;//a的值将不可以改变
常量的特征:
- 常量必须在声明时初始化。指定了其值以后,就不能再修改了。
- 常量的值必须能在编译时用于计算。因此不能从一个变量中提取的值来初始化常量。如果需要这么做,应该使用只读字段。
- 常量总是静态的,但注意,不必在常量的声明中包含修饰符static。(实际上,不允许)
在程序中使用常量至少有3个好处:
- 常量用易于理解的清楚的名称替代了含义不明确的数字或者字符串,使得程序更加易于阅读。
- 常量使程序更容易修改。例如在C#程序中有一个SalesTax常量,该常量的值为6%。如果以后销售税率发生变化,把新值赋给这个常量,就可以修改所有的税款计算结果,而不必查找整个程序,修改税率为0.06的每个项。
- 常量更容易避免程序出现错误。如果要把另一个值赋给程序中的一个常量,而该常量已经有了一个值,编译器就会报告错误。
如以下程序:
namespace Test
{
class ScopeTest
{
static int j=;
const string time= DateTime.Now.ToString();
public static void Main()
{
int j=;
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=;
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定义变量是需要一些规则的。变量必须初始化。否则,编译器就没有推断变量类型的依据。初始化器不能为空,且必须放在表达始中。不能把初始化器设置为一个对象,除非在初始化器中创建一个新对象。
三、变量的作用域
变量的作用域是可以访问该变量的代码区域。一般情况下,确定作用域有一下规则:
- 只要类在某个作用域内,其字段也在该作用域内
- 局部变量存在于声明该变量的块语句或方法结束的封闭花括号之前的作用域内。
- 在for、while或类似语句中声明的局部变量存在与该循环体内
大型程序的不同部分为不同的变量提供相同的变量名很常见。只要变量的作用域是程序的不同部分,就不会有问题。也不会产生模糊。但要注意,同名的局部变量不能在同一作用域内声明两次,所以如下代码是不能使用的:
int x=20;
int x=30;
再来看如下例子:
using System;
namespace wpfworld.com
{
pulic static int main()
{
For(int i=;i<;i++)
{
Console.writeLie(i);
}
For(int i=;i>=;i—
{
Console.WriteLine(i);
}
}
}
这段代码需要引起我们的注意。i出现了两次,但是他们都是相对于循环体的变量。
另一个例子:
public static int Main()
{
int j=;
for(int i=;i<;i++)
{
int j=;//错误
Console.WriteLine(j+i);
}
return ;
}
这里会发生错误,因为变量j是在for循环开始前定义的,在执行for循环时应处于其作用域内,在Main方法执行后,变量j才超出作用域,第二个j(不合法)则在循环的作用域内,在作用域嵌套在Main方法的作用域内,编译器无法区别这两个变量。
字段或局部变量的作用域冲突:在某些情况下,可以区分名称相同(尽管其完全限定的名称不同)、作用域项目的两个标识。此时编译器允许声明第二个变量。原因是C#在变量之间有一个基本的区分,它把声明为类型级的变量字段看作字段,而把在方法中声明的变量看作局部变量。
C#中的常量、类型推断和作用域的更多相关文章
- Go值类型和引用类型+作用域+空白标识符+常量
值类型和引用类型 所有像 int.float.bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值: 当使用等号 = 将一个变量的值赋值给另一个变量时,如:j ...
- C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)
#include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...
- javascript中对变量类型的推断
本文正式地址:http://www.xiabingbao.com/javascript/2015/07/04/javascript-type 在JavaScript中,有5种基本数据类型和1种复杂数据 ...
- java8中对lamdba表达式方法参数传递时,方法重载之后的类型推断
java8中可以向方法传递一个lamdba表达式,今天看书关于类型推断碰到一个问题: 这个问题我实际操作了一下:得出结论 如果是只有一个方法的情况下,方法参数使用lamdba表达式的时候是不需要写类型 ...
- Java中的变量与变量的作用域
关于Java中的变量及变量的作用域 关于Java中的变量及变量的作用域 0. 变量的概念 在程序运行期间,系统可以为程序分配一块内存单元,用来存储各种类型的数据.系统分配的内存单元要使用一个标记符来标 ...
- Swift语言指南(四)--类型安全和类型推断
原文:Swift语言指南(四)--类型安全和类型推断 Swift是一门类型安全语言,类型安全语言需要代码里值的类型非常明确.如果你的代码中有部分值需要String类型,你就不能错误地传递Int. 鉴于 ...
- Android-Kotlin-when&类型推断
Kotlin的when表达式 TextEngine 描述文字处理对象: package cn.kotlin.kotlin_base02 /** * 描述文字处理对象 * * val textConte ...
- 译:Java局部变量类型推断(Var类型)的26条细则
原文链接:https://dzone.com/articles/var-work-in-progress 作者:Anghel Leonard 译者:沈歌 Java局部变量类型推断(LVTI),简称va ...
- [原创]Scala学习:关于变量(val,var,类型推断)
1.常量定义: val val 类似于java中的final变量.一旦初始化了,val就不能再被赋值 val megs = "hello world" 2.变量的定义: var ...
随机推荐
- 【翻译自mos文章】在12c中Create or Truncate Table时非常慢,等待事件为 DFS Lock Handle wait
来源于: Create or Truncate Table Slow in 12c While Waiting for DFS Lock Handle wait (文档 ID 2085308.1) A ...
- MSMQ消息队列的安装、启用
最近研究消息队列,先从微软自带的MSMQ开始,百度如何安装,方式如下: 控制面板---程序和功能--启用和关闭windows功能--Microsoft Message Queue(MSMQ)服务器 默 ...
- Django的缓存,序列化,ORM操作的性能
1,缓存:把数据先保存在某个地方,下次再读取的时候不用再去原位置读取
- JS之RegExp对象(二)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zkn_CS_DN_2013/article/details/24243159 RegExp对象的经常 ...
- http_load常见问题及解决方案
1.错误信息:byte count wrong http_load在处理时会去关注每次访问同一个URL返回结果(即字节数)是否一致,若不一致就会抛出byte count wrong 所以动态页面可以忽 ...
- 《JAVA与模式》之责任链模式
责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...
- Pessimistic Offline Lock悲观离线锁
每次只允许一个业务事务来访问数据,以防止并发业务事务中的冲突. 离线并发处理通常会出现多个业务事务操作同一数据. 最简单的办法是为整个业务事务保持一个系统事务.但是事务系统不适合于处理长事务. 首选乐 ...
- bzoj 3944: Sum【莫比乌斯函数+欧拉函数+杜教筛】
一道杜教筛的板子题. 两个都是积性函数,所以做法是一样的.以mu为例,设\( f(n)=\sum_{d|n}\mu(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1} ...
- P5089 [eJOI2018]元素周期表(并查集)
传送门 以后看到棋盘要么黑白染色要么二分图! 我们考虑对行列建二分图,如果\(i\)行\(j\)列有,就把\(i\)和\(j+n\)连起来 我们要让它变成一张完全二分图.考虑条件\((i_1,j_1+ ...
- [App Store Connect帮助]七、在 App Store 上发行(1)App 发行流程概述
在 App Store 上发行 App 的一般流程如下. 第 1 步:选择您的构建版本 每个 App 都可以有多个版本,且每个版本也可以有多个构建版本.若要在 App Store 上发行您的 App, ...