99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

C# 作用域

2018-09-28 18:42 更新

作用域

名稱的作用域(scope)是一個程序文本區(qū)域(region),在其中可以用過名稱引用實體聲明而不對該名稱加以限定條件(qualification)。作用域可嵌套,內(nèi)部作用域可重聲明外部作用域名稱的含義(但這并不會移除在第三章第三節(jié)中對其的限制——在嵌套塊內(nèi)不能聲明與閉包塊(enclosing block)內(nèi)局部變量同名的局部變量)。因此可以說此外部作用域的名稱在該內(nèi)部作用域覆蓋的程序文本區(qū)域內(nèi)是隱藏(hidden)的,只能通過限定名來訪問外部名稱。

  • namespace-member-declaration(第九章第五節(jié))聲明的命名空間成員的作用域——如果沒有其它 namespace-declaration 對其閉包的話——是整個(entire)程序文本。
  • namespace-declaration 內(nèi)的 namespace-member-declaration 聲明的命名空間成員的作用域是——如果假設該命名空間成員聲明的完全限定名為 N——完全限定名為 N 或以 N 為始、后跟一個句號(period)的每個 namespace-declarationnamespace-body。
  • extern-alias-directive 定義的名稱的作用域擴展到直接包含其編譯單元或命名空間主體的 using-directives、global-attributesnamespace-member-declarations。extern-alias-directive 并不會為底層聲明空間(underlying declaration space)增加任何成員。換句話說 extern-alias-directive 并不具傳遞性,相反其只會影響到在其內(nèi)出現(xiàn)的 compilation-unitnamespace-body。
  • using-directive(第九章第四節(jié))定義或導入的名稱的作用域擴展到出現(xiàn) using-directivecompilation-unitnamespace-body 的整個 namespace-member-declarations。using-directive 能使零或多個命名空間或類型名在特定的 compilation-unitnamespace-body 變得可用,但并不會為底層聲明空間(underlying declaration space)增加任何成員。換句話說 using-directive 并不具傳遞性,相反其只會影響到在其出現(xiàn)的 compilation-unitnamespace-body。
  • 由一個在 class-declaration(第十章第一節(jié))中的 type-parameter-list 所聲明的類型形參的作用域是該 class-declarationclass-basetype-parameter-constraints-clauses 以及 class-body。
  • 由一個在 struct-declaration(第十一章第一節(jié))中的 type-parameter-list 所聲明的類型形參的作用域是該 struct-declarationstruct-interfacestype-parameter-constraints-clauses 以及 struct-body。
  • 由一個在 interface-declaration(第十三章第一節(jié))中的 type-parameter-list 所聲明的類型形參的作用域是該 interface-declarationinterface-base、type-parameter-constraints-clauses 以及 interface-body。
  • 由一個在 delegate-declaration(第十五章第一節(jié))中的 type-parameter-list 所聲明的類型形參的作用域是該 delegate-declarationreturn-typeformal-parameter-list 以及 type-parameter-constraints-clauses。
  • class-member-declaration(第十章第 1.6 節(jié))所聲明的成員的作用域位于該聲明所出現(xiàn)的 class-body 之內(nèi)。此外,類成員的作用域擴展到包含該成員且為可訪問的(accessibility,第三章第 5.2 節(jié))派生類的 class-body。
  • struct-member-declaration(第十一章第二節(jié))聲明的成員的作用域位于該聲明出現(xiàn)的 struct-body 之內(nèi)。
  • enum-member-declaration(第十四章第三節(jié))所聲明的成員的作用域位于該聲明出現(xiàn)的 enum-body 內(nèi)。
  • 位于 method-declaration(第十章第六節(jié))內(nèi)所聲明之參數(shù)的作用域是該 method-declarationmethod-body。
  • 位于 indexer-declaration(第十章第九節(jié))內(nèi)所聲明之參數(shù)的作用域是該 indexer-declarationaccessor-declarations。
  • 位于 operator-declaration(第十章第十節(jié))內(nèi)所聲明之參數(shù)的作用域是該 operator-declaration 的 block。
  • 位于 constructor-declaration(第十章第十一節(jié))內(nèi)所聲明之參數(shù)的作用域是該 constructor-declarationconstructor-initializerblock。
  • 位于 lambda-declaration(第七章第十五節(jié))內(nèi)所聲明之參數(shù)的作用域是該 lambda-expressionlambda-expression-body。
  • 位于 anonymous-method-expression(第七章第十五節(jié))內(nèi)所聲明之參數(shù)的作用域是該 anonymous-method-expressionblock
  • 位于 labeled-statement(第八章第四節(jié))內(nèi)所聲明之標簽的作用域是該聲明所在的 block。
  • 位于 local-variable-declaration(第八章第 5.1 節(jié))內(nèi)所聲明之局部變量的作用域是該聲明所在的 block。
  • 位于 switch 語句(第八章第 8.3 節(jié))的 switch-block 內(nèi)所聲明的局部變量的作用域是該 switch-block。
  • 位于 for 語句(第八章第 8.3 節(jié))的 for-initializer 內(nèi)所聲明的局部變量的作用域是該語句的 for-initializer、for-conditionfor-iterator 以及所含之 statement。
  • 位于 local-constant-declaration(第八章第 5.2 節(jié))內(nèi)聲明的局部變量的作用域是該聲明出現(xiàn)的 block。在該局部變量的 constant-declarator 之前的文本位置上引用該局部變量將出現(xiàn)一個「編譯時錯誤」。
  • 作為 foreach-statement、using-statement、lock-statementquery-expression 一部分所聲明的變量的作用域由給定構造(construct)的擴展(expansion)所決定。

在命名空間、類、結構或枚舉成員的作用域內(nèi),可以在位于該成員聲明之前的文本位置上引用該成員。比方說

class A
{
    void F() {
        i = 1;
    }
    int i = 0;
}

在此,F(xiàn) 在 i 聲明之前引用它是合法的。

在局部變量的作用域內(nèi),當引用局部變量的文本位置(textual position)在該局部變量聲明之前(local-variable-declarator)會出現(xiàn)一個「編譯時錯誤」。比方說

class A
{
    int i = 0;
    void F() {
        i = 1;   // 錯誤,在使用前先聲明
        int i;
        i = 2;
    }
    void G() {
        int j = (j = 1);     // 有效
    }
    void H() {
        int a = 1, b = ++a;  // 有效
    }
}

在上面方法 F 中,第一個對 i 的賦值實際上并不會引用外部作用域的字段。相反,它引用了本地局部變量,而其結果是引發(fā)一個「編譯時錯誤」,因為在文本上要求先聲明變量。在方法 G 中,為 j 進行聲明的同時在其初始化器內(nèi)使用 j 是有效的,這是因為并沒有在 local-variable-declarator 之前使用。在方法 H 中,后面的 local-variable-declarator 正確引用了局部變量(該局部變量在同一個 local-variable-declarator 內(nèi)前面那個 local-variable-declarator 中聲明了)。

本地布局變量的作用域規(guī)則被設計為保證(guarantee)表達式上下文(expression context)中使用的名稱的含義與在塊中使用的含義是相同的。如果局部變量的作用域只從其聲明之處其,到塊尾部截止,那么在上例中,第一個賦值將分配給實例變量(instance variable),第二次賦值將分配給局部變量,如果塊中的語句之后重新排列,會引發(fā)「編譯時錯誤」。

塊(block)中名稱的含義可能因名稱的使用上下文的不同而有所不同。在下例中,

using System;
class A {}
class Test
{
    static void Main() {
        string A = "hello, world";
        string s = A;         // 表達式上下文
        Type t = typeof(A);   // 類型上下文
        Console.WriteLine(s); // 輸出 "hello, world"
        Console.WriteLine(t); // 輸出 "A"
    }
}

在表達式上下文中的名稱 A 引用本地變量 A,在類型上下文中引用類型 A

名稱隱藏

實體(entity)的作用域(scope)往往比實體聲明空間包含(encompasses)更多的程序文本。具體來說,實體的作用域可能會引入新的聲明空間,而其中或許會包含與該實體同名的實體。這類聲明導致原始實體變?yōu)?strong>隱藏的(hidden)。相反,如果實體沒有被隱藏,那么我們說它是可見的(visible)。

當作用域通過嵌套交叉(overlap)或當作用域通過繼承交叉,那么會導致名稱隱藏。兩個被隱藏的類型的特征在下面兩節(jié)中進行介紹。

通過嵌套隱藏

在命名空間內(nèi)嵌套命名空間或類型,或者在類或結構內(nèi)嵌套類型,以及性參與局部變量的聲明,都將導致嵌套隱藏(hiding through nesting)名稱。舉個例子。

class A
{
    int i = 0;
    void F() {
        int i = 1;
    }
    void G() {
        i = 1;
    }
}

在方法 F 內(nèi),實例變量 i 被局部變量 i 所隱藏,但在方法 G 內(nèi),i 依舊引用實例變量。

當內(nèi)部作用域的名稱隱藏了外部作用域的名稱時,它將隱藏該名稱的所有重載。下例中,

class Outer
{
    static void F(int i) {}
    static void F(string s) {}
    class Inner
    {
        void G() {
            F(1);        // 調(diào)用 Outer.Inner.F
            F("Hello");  // 錯誤
        }
        static void F(long l) {}
    }
}

調(diào)用(call)F(1) 將調(diào)用(invokes)內(nèi)部聲明的 F,這是因為所有外部出現(xiàn)的 F 都被內(nèi)部聲明所隱藏。同樣的,調(diào)用 F("Hello") 的結果是出現(xiàn)「編譯時錯誤」。

通過繼承隱藏

當類或結構重新聲明(redeclare)從基類繼承的名稱時,會發(fā)生通過繼承隱藏(hiding through inheritance)其名稱。這種類型的名稱隱藏采取以下形式:

  • 常量、字段、屬性、事件或類型引入類或結構后,會隱藏所有基類中的同名成員。
  • 方法引入類或結構將隱藏所有同名的非方法基類成員(non-method base class members)和所有同簽名(方法名、參數(shù)數(shù)量、修飾符與類型)的基類方法。
  • 索引器引入類或結構將隱藏所有同簽名(參數(shù)數(shù)量與類型)的基類索引。

管理運算符聲明(governing operator declarations,第十章第十節(jié))的規(guī)則使其不可能在派生類中聲明一個與其基類內(nèi)同簽名的運算符。因此,操作符不能相互隱藏。

與從作用域外部對名稱進行隱藏相反,通過繼承的作用域隱藏名稱可訪問性會報出警告。下例中,

class Base
{
    public void F() {}
}
class Derived: Base
{
    public void F() {}  // 警告,隱藏了繼承到的名稱
}

派生類 DerivedF 的聲明會導致一個警告。隱藏所繼承的名稱實際上不是一個錯誤,因為這會妨礙基類自身的單獨改進。比方說,上述情況可能會發(fā)生因為 Base 的后續(xù)版本可能會引入一個 F 方法(而這個方法在之前版本中沒有)。如果上述情況是錯誤的,那么對單獨版本控制的基類的任何變化都會潛在導致派生類變得無效。

因隱藏繼承到的名字而引發(fā)的警告可通過 new 修飾符消除:

class Base
{
    public void F() {}
}
class Derived: Base
{
    new public void F() {}
}

修飾符 new 表示派生類 Derived 中的 F 是「新的」,它將隱藏所繼承到的(同簽名)成員。新成員的聲明將隱藏其所繼承到的,當且僅當位于新成員的作用域內(nèi)。

class Base
{
    public static void F() {}
}
class Derived: Base
{
    new private static void F() {} // 只會隱藏 Derived 內(nèi)的 Base.F
}
class MoreDerived: Derived
{
    static void G() { F(); }       // 調(diào)用 Base.F
}

上例中,派生類中的 F 聲明隱藏了(hide)其從基類繼承到的 F。但由于派生類中新 F 的可訪問性是 private,因此它的作用域達不到 MoreDerived。因此 MoreDerived.G 調(diào)用(call) F() 方法依舊合法,它將調(diào)用 Base.F

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號