C# 运用作用域

前面已经展示了一些在方法内部创建变量的例子。变量从定义了它的语句开始存在,同一个方法内的后续语句可以使用该变量。换言之,变量只能在创建了之后才能使用。方法执行完毕后,变量也会彻底消失。

假如一个变量能在程序中的一个特定位置使用,就说明该变量具有那个位置的作用域。也就是说,一个变量的作用域(scope)是指能够使用该变量的程序区域。作用域既作用于方法,也作用于变量。一个标识符(不管它代表变量还是代表方法)的作用域是从声明明该标识符的那个位置开始的。

定义局部作用域

界定方法主体的起始与结束大括号建立了一个作用域。方法主体中声明的任何变量都具有那个方法的作用域;一旦方法结束,它们也会消失,而且只能由那个方法内部执行的代码来访问。这些变量称为局部变量(local variable),因为它们局限于声明它们的那个方法,不能在其他任何方法的作用域中使用。换言之,你不能使用局部变量在不同的方法之间共享信息。例如:
 
class Example
{
    void firstMethod()
    {
        int myVar;
        ...
    }
    void anotherMethod()
    {
        myVar = 42; // 错误 – 变量越界
        ...
    }
}

上述代码将编译失败,因为anotherMethod方法试图使用一个越界的myVar变量。该变量只能由firstMethod方法中的语句使用。

定义类作用域

界定类主体的起始和结束大括号也建立了一个作用域。在类主体中(但不在一个方法中)声明的任何变量都具有那个类的作用域。在C#术语中,开发者使用字段(field)一词来描述由一个类定义的变量。和局部变量不同,你可以使用字段在不同的方法之间共享信息。    例如:
 
class Example
{
    void firstMethod()
    {
        myField = 42; // ok
        ...
    }
    void anotherMethod()
    {
        myField = 42; // ok
        ...
    }
    int myField = 0;
}

变量myField是在类的内部以及firstMethod和anotherMethod方法的外部定义的。所以,myField具有类的作用域,可由类中的所有方法使用。

这个例子中还需要注意另一点。在一个方法中,必须在使用一个变量前声明它。但字段稍有不同,一个方法能在定义一个字段的语句之前使用那个字段——在这种情况下,编译器将为你打点一切!

重载方法

如果两个标识符同名,而且在同一个作用域中声明,就可以说它们被重载(overloaded)。通常,重载的标识符属于一个程序bug,会在编译时被捕捉到并报错。例如,假定你在同一个方法中声明了两个同名的局部变量,就会获得一个编译时错误。类似地,假如在同一个类中声明了同名的两个字段,或者在同一个类中声明了两个完全一样的方法,就会获得一个编译时错误。这个事实表面上似乎不值一提,因为一切都会被报告为编译时错误。然而,你确实能通过一种方式来重载标识符,而且这种重载不仅是有用的,而且是重要的。

以Console类中的WriteLine方法为例,前面已经使用该方法向屏幕输出一个字符串。然而,在“代码和文本编辑器”窗口中输入WriteLine时,会自动弹出一个“智能感知”列表,其中列出了19个不同的版本!WriteLine方法的每个版本都获取一套不同的参数。一个实现不获取任何参数,只是输出一个空行;另一个实现则获取一个bool参数,并输出它的值的字符串形式(true或false);还有一个实现获取一个小数值,并以字符串的形式输出它;等。程序编译时,编译器会检查所传递的实参的类型,然后调用参数集与之匹配的一个方法版本。下面是一个例子:
 
static void Main()
{
    Console.WriteLine("The answer is ");
    Console.WriteLine(42);
}

如果需要针对不同的数据类型执行相同的操作,重载就是一项十分有用的技术。如果不同的实现有不同的参数集,就可以考虑重载一个方法。换言之,每个版本都具有相同的方法名,但具有不同的参数数量或者不同的参数类型。利用这个功能,在调用一个方法时,可以提供一个以逗号分隔的实参列表,而编译器将根据这些实参的数量和类型,选择其中的一个匹配的重载版本。但要注意,虽然可以重载一个方法的参数,但不能重载方法的返回类型。也就是说,不能声明只是返回类型有区别的两个同名方法(编译器虽然比较聪明,但还不至于聪明到那种程度)。

时间: 2024-10-07 22:41:05

C# 运用作用域的相关文章

一招制敌 - 玩转 AngularJS 指令的 Scope (作用域),讲得特别好

学习了AngularJS挺长时间,最近再次回首看看指令这部分的时候,觉得比自己刚开始学习的时候理解的更加深入了,尤其是指令的作用域这部分. 步入正题: 每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope参数提供了三种选择,分别是:false,true,{}:默认情况下是false. scope = false 首先我们来看

CSS作用域问题

今天去长虹面试,面试官问了一个问题,就是给一个div在三个地方设置不同的background,最后div显示的颜色是哪一个?当时我第一次回答的是最后一个,但是后来又改口说是第一个,回来一验证,证明自己错了,今天就总结一下CSS样式的作用域问题吧. 首先对HTML引入样式的优先级排序,数字越大优先级越高#### 样式优先级1. 浏览器缺省设置2. 外部样式表3. 内部样式表(位于 <head> 标签内部)4. 内联样式(在 HTML 元素内部) ---#### 外部样式表>浏览器缺省设置H

JavaScript的进阶之路(二)函数简介,变量、作用域和内存问题

<h3>ECMAScript中函数不存在函数签名的概念,没有重载</h3><h3>无需指定返回值,可以在任何时候返回任何值.未指定返回值的函数,返回的是一个特殊的undefined值</h3> <script type="text/javascript"> function sayHi(){ console.log("Hi"); }; sayHi(); function sayName(name,age){

JavaScript栈和堆内存,作用域

1.栈 stack"和"堆 heap": 简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态分配内存,heap上一般是动态分配内存. 2.基本类型和引用类型: 基本类型:存放在栈内存中的简单数据段.数据大小确定,内存空间大小可以分配. 引用类型:存放在堆内存中的对象,变量中实际保存的是一个指针,这个指针指向另一个位置.每个空间大小不一样,要根据情况开进行特定的分配. 详见<Javas

深入理解javascript的作用域--函数声明为什么会前置

标签: javascript函数对象 这篇博文解决了以下迷惑 函数声明为什么前置 函数声明前置和变量前置优先级问题 为什么js文件开头就可以使用Math,String等库,而不需要导入头文件 1.变量对象VO 变量对象(Variable Object, 缩写为VO)是一个抽象 概念中的"对象",它用于存储执行上下文中的: 1. 变量 2. 函数声明 3. 函数参数 js解释器就是通过变量对象(VO)来找到我们定义的变量和函数的. 举个例子: var a = 10; function t

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动

Python之路18-函数作用域、全局变量、局部变量

#全局变量 school = 'lianhedaxue' def test(name):     #强制修改全局变量     global school     school = 'haha'     print ('before change',name,school)     name = 'Jack'   #这个函数就是这个变量的作用域     print ('after change',name) name = 'Tom' test(name) print (name) print (s

javascript变量声明和作用域提升

以前的知识总是忘,遇到代码又看不懂.要再复习一下,顺便记录一下. 1 add(1,2); 2 function add(a,b){ 3 alert(a+b); 4 } 代码能输出3,为什么不是按顺序执行?应该是  //add is not defined ... javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 也就是说,function add(a,b){alert(a+b)}是一个函数声明,告诉我们有

【】五句话搞定JavaScript作用域

JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个作用域.  Java  C# 在JavaScript语言中无块级作用域 1 2 3 4 5 6 7 function Main(){     if(1==1){         var name = 'seven';     }     console.log(n

面向对象之对象,作用域及this

object eg: var o = { a : 2, b : 3 }; console.log(o); console.log(typeof o); console.log(o.a.toFixed(2)); ==> var o = new Object(); o.a = 2; o.b = 3; console.log(o); console.log(typeof o); console.log(o.a.toFixed(2)); eg: var person = { name: “张三”, ag