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 ...
随机推荐
- 2016/04/18 session cookie 对比 应用 <?php session_start() / setcookie()?>
①会话 huihua.php <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- iOS开发——高级篇——iOS抽屉效果实现原理
实现一个简单的抽屉效果: 核心思想:KVO实现监听mainV的frame值的变化 核心代码: #import "ViewController.h" // @"frame& ...
- myeclipse包的层数和package的层数不一致
复制别人的工程的时候常常遇到包的层数不一致的情况 如下图 其实com.weibo.happpy.dao的上面还有一层java包,但是代码里没有写java....... 可以通过如下方式修改工程:
- Knn算法C++实现
相对简单的模拟.C++11 /* *********************************************** Author :guanjun Created Time :2016/ ...
- 使用cloudflare加速你的网站隐藏你的网站IP
前言 cloudflare 是一家国外的 CDN 加速服务商,还是很有名气的.提供免费和付费的加速和网站保护服务.以前推荐过的百度云加速的国外节点就是和 cloudflare 合作使用的 cloudf ...
- linux下开机启动svn配置
1.在 vi /etc/rc.local文件下添加以下: /home/svn/subversion-1.8.18/bin/svnserve -d --listen-port 3690 -r /home ...
- C# ref和out总结
C# 中ref 与 out 总结 参数的传递一般分为两种:一种是“值传递”即:传递实参的拷贝,既然是拷贝那么在函数中对这个形参所作的任何动作都不会反映到原来的实参中.另外一种是“引用传递”即:传递 ...
- python库学习笔记——BeautifulSoup处理子标签、后代标签、兄弟标签和父标签
首先,我们来看一个简单的网页https://www.pythonscraping.com/pages/page3.html,打开后: 右键"检查"(谷歌浏览器)查看元素: 用导航树 ...
- 如何编写linux下nand flash驱动-2
[Nand Flash引脚(Pin)的说明] 图3.Nand Flash引脚功能说明 上图是常见的Nand Flash所拥有的引脚(Pin)所对应的功能,简单翻译如下: 1. I/O0 ~ ...
- Lightoj 1068(数位DP)
求一段区间中被k整除,各个位数相加之和被k整除的数的个数. 这不是重点,重点是k太大了,最大值有10000,所以不能直接开那么大的数组. 仔细分析一下可以发现,由于数最大是2的31次方(2147483 ...