譯自Eric Lippert's Blog, 原文: http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx
在程式語言設計中,作用域(scope)通常是最容易混淆的概念。
人們似乎不經意間就使用這個概念,我經常看到它被當做生存期(lifetime)或定義空間(declaration space)使用,例如"當這個變數超出作用域時,對應的記憶體空間將被釋放"。當然在非正式場合,只要聽眾能清楚地理解你所指的意思,使用"作用域"來表示是完全可以接受的。但是在更正式的場合,比如書中或語言標準中,就需要更精確地使用這些概念。
C#中作用域和定義空間的區別是微妙的。
一個命名實體(entity)的作用域是原始碼中可以合法使用它的非限定名(unqualified name)來引用它的範圍。
這裡有些微妙的東西, 這個定義並沒有別的隱含的意思 -- 它並非表示如果你可以合法使用一個實體的非限定名,則通過這個非限定名就可以引用這個實體。因為作用域是允許重疊(overlap)的。例如,如果有以下程式碼:
{
int x;
void M()
{
int x;
}
}
欄位x(field)的作用域是原始碼中類C(class)的整個定義部分,包括方法M(method)的整個定義;區域性變數x(local variable)的作用域是方法M的主體部分。所以這兩個實體的作用域有重疊的部分。當你在不同的位置使用非限定名"x",將得到不同的實體(欄位x或者區域性變數x)。
相反, 定義空間是一段其中不允許存在具有相同名稱實體的原始碼範圍。例如,在類C的定義部分,除了方法M的主體部分,不允許別的實體也命名為x。一旦定義了個欄位x, 就不能再定義別的稱為x的欄位,屬性(property), 內嵌型別(nested type)或事件(event)。
正因為有過載機制(overload), 使得方法有一點特殊。可以特別定義有方法的定義空間為"一個類中所有具有相同名稱的過載方法構成一個實體", 也可以重新定義定義空間為"定義空間中不允許存在具有相同名稱的實體, 除了具有不同簽名(signature)的方法"。
簡短地說,作用域解決了“在哪裡可以使用這個名稱”的問題;名稱空間解決了“這個名稱在哪裡是唯一的”的問題。
生存期和作用域經常在區域性變數上容易混淆,因為在區域性變數上這兩者關係太複雜了。扼要地講,就是隻要當前的執行點(point of execution)在區域性變數的作用域內,至少能保證它的內容可用。但也可能區域性變數的內容在超出它的作用域外也是可用的,比如捕獲變數(capture variable, variable capturing , 在匿名函式中使用外部變數 )將擴充套件這個變數的生存期。