Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
14.1 Általános
A C#-programok névterek használatával vannak rendszerezve. A névterek mind a programok "belső" szervezeti rendszereként, mind pedig "külső" szervezeti rendszerként használatosak – ez a más programok számára elérhető programelemek bemutatásának módja.
A névterek használatának megkönnyítése érdekében irányelveket (14.5. §) kell alkalmazni.
14.2 Fordítási egységek
A compilation_unit nullából vagy több extern_alias_directive, majd nullából vagy több using_directives-ből, majd nullából vagy egy global_attributes és egy namespace_member_declarations-ből áll. A compilation_unit határozza meg a bemenet általános szerkezetét.
compilation_unit
: extern_alias_directive* using_directive* global_attributes?
namespace_member_declaration*
;
A C#-programok egy vagy több fordítási egységből állnak. Egy C#-program fordításakor az összes fordítási egység együtt lesz feldolgozva. Így a fordítási egységek egymástól függhetnek, esetleg körkörös módon.
A fordítási egység extern_alias_directives-i hatással vannak a fordítási egység using_directive, global_attributes és namespace_member_declarations-ére, de nincs hatással más fordítási egységekre.
A fordítási egység using_directives-i hatással vannak a fordítási egység global_attributes és namespace_member_declarations-jára, de nincs hatással más fordítási egységekre.
A fordítási egység global_attributes (23.3. §) lehetővé teszi a célszerelvény és modul attribútumainak specifikációját. A szerelvények és modulok fizikai tárolóként működnek a típusok esetében. Egy szerelvény több fizikailag különálló modulból állhat.
A programegyes fordítási egységeinek namespace_member_declaration tagjai egyetlen deklarációs térhez, a globális névtérhez járulnak hozzá.
Example:
// File A.cs: class A {} // File B.cs: class B {}A két fordítási egység hozzájárul az egyetlen globális névtérhez, ebben az esetben két osztályt deklarál a teljes névvel
AésB. Mivel a két összeállítási egység ugyanahhoz a deklarációs területhez járul hozzá, hiba lett volna, ha mindegyik egy azonos nevű tag deklarációját tartalmazza.záró példa
14.3 Névtér deklarációk
A namespace_declaration a kulcsszó névteréből, majd egy névtérnévből és egy törzsből állnak, amelyet igény szerint pontosvessző követ.
namespace_declaration
: 'namespace' qualified_identifier namespace_body ';'?
;
qualified_identifier
: identifier ('.' identifier)*
;
namespace_body
: '{' extern_alias_directive* using_directive*
namespace_member_declaration* '}'
;
A namespace_declaration egy compilation_unit legfelső szintű deklarációjaként vagy egy másik namespace_declaration belüli tagi deklarációként is előfordulhat. Ha egy namespace_declaration egy compilation_unit legfelső szintű deklarációjaként történik, a névtér a globális névtér tagjává válik. Ha egy namespace_declaration egy másik namespace_declaration belül történik, a belső névtér a külső névtér tagjává válik. A névtér nevének mindkét esetben egyedinek kell lennie az azt tartalmazó névtéren belül.
A névterek implicitek public , és a névtér deklarációja nem tartalmazhat hozzáférési módosítókat.
Egy namespace_body belül az opcionális using_directivemás névterek, típusok és tagok nevét importálják, így közvetlenül hivatkozhatnak rájuk a minősített nevek helyett. A választható namespace_member_declarationtagokat a névtér deklarációs területéhez. Vegye figyelembe, hogy minden using_directivemeg kell jelennie a tagi nyilatkozatok előtt.
A namespace_declaration qualified_identifier lehet egyetlen azonosító vagy azonosítósorozat, amelyet "." jogkivonatok választanak el egymástól. Az utóbbi űrlap lehetővé teszi, hogy a program több névtérdeklaráció lexikális beágyazása nélkül definiáljon beágyazott névteret.
Example:
namespace N1.N2 { class A {} class B {} }szemantikailag egyenértékű a
namespace N1 { namespace N2 { class A {} class B {} } }záró példa
A névterek nyitott végűek, és két azonos teljes névvel rendelkező névtér-deklaráció (7.8.3. §) járul hozzá ugyanahhoz a deklarációs térhez (7.3. §).
Példa: Az alábbi kódban
namespace N1.N2 { class A {} } namespace N1.N2 { class B {} }a fenti két névtér-deklaráció ugyanahhoz a deklarációs térhez járul hozzá, ebben az esetben két osztályt deklarál a teljes névvel
N1.N2.AésN1.N2.B. Mivel a két deklaráció ugyanahhoz a deklarációs térhez járul hozzá, hiba lett volna, ha mindegyik egy azonos nevű tag deklarációját tartalmazza.záró példa
14.4 Extern alias irányelvek
Egy extern_alias_directive egy névtér aliasaként szolgáló azonosítót vezet be. Az aliasos névtér specifikációja kívül esik a program forráskódán, és az aliasos névtér beágyazott névtereire is vonatkozik.
extern_alias_directive
: 'extern' 'alias' identifier ';'
;
A extern_alias_directive hatóköre az azonnali compilation_unitvagy namespace_bodytartalmazó using_directive, global_attributes és namespace_member_declaration s-ére terjed ki.
Egy extern_alias_directive tartalmazó összeállítási egységben vagy névtértörzsben a extern_alias_directive által bevezetett azonosító használható az aliasos névtérre való hivatkozáshoz. Fordítási időhiba, hogy az azonosító legyen a szó global.
A extern_alias_directive által bevezetett alias nagyon hasonlít a using_alias_directive által bevezetett aliashoz. Az extern_alias_directives és using_alias_directiverészletesebb ismertetését a 14.5.2.
aliasegy környezetfüggő kulcsszó (6.4.4.4. §), és csak akkor van különleges jelentése, ha azonnal követi a extern egy extern_alias_directive.
Hiba akkor fordul elő, ha egy program olyan extern aliast deklarál, amelyhez nincs megadva külső definíció.
Példa: A következő program két extern aliast deklarál és használ,
XamelyekYmindegyike egy különálló névtérhierarchia gyökerét jelöli:extern alias X; extern alias Y; class Test { X::N.A a; X::N.B b1; Y::N.B b2; Y::N.C c; }A program deklarálja a kiirtott aliasok
Xmeglétét, deYaz aliasok tényleges definíciói külsőek a programon. A névtér alias-minősítője ésN.Ba névtér aliasának minősítőjekéntX.N.BY.N.Bés néven hivatkozhatX::N.Baz azonos nevűY::N.Bosztályokra. záró példa
14.5 Irányelvek használata
14.5.1 Általános
A használati irányelv megkönnyíti a más névterekben definiált névterek és típusok használatát. Az irányelvek használata hatással van namespace_or_type_name s (7.8. §) és simple_name(12.8.4. §) névfeloldási folyamatára, de a deklarációkkal ellentétben a using_directive-eknem járulnak hozzá új tagokhoz azon összeállítási egységek vagy névterek mögöttes deklarációs tereihez, amelyeken belül használják őket.
using_directive
: using_alias_directive
| using_namespace_directive
| using_static_directive
;
A using_alias_directive (14.5.2. §) egy névtérhez vagy típushoz tartozó aliast vezet be.
Egy using_namespace_directive (14.5.3. §) importálja a névtér típustagokat.
Egy using_static_directive (14.5.4. §) importálja egy típus beágyazott típusait és statikus tagjait.
A using_directive hatóköre a fordítási egységet vagy névtértörzset közvetlenül tartalmazó namespace_member_declarations terjed ki. A using_directive hatóköre nem tartalmazza a társ using_directive. Így a társ using_directivenem érintik egymást, és a megírásuk sorrendje jelentéktelen. Ezzel szemben a extern_alias_directive hatóköre magában foglalja az ugyanabban a fordítási egységben vagy névtértörzsben definiált using_directive.
14.5.2 Alias irányelvek használata
A using_alias_directive olyan azonosítót vezet be, amely aliasként szolgál egy névtérhez vagy típushoz az azonnali összeállítási egység vagy névtér törzsén belül.
using_alias_directive
: 'using' identifier '=' namespace_or_type_name ';'
;
A using_alias_directive tartalmazó összeállítási egység vagy névtértörzs globális attribútumaiban és tagdeklarációiban a using_alias_directive által bevezetett azonosító használható a megadott névtérre vagy típusra való hivatkozáshoz.
Example:
namespace N1.N2 { class A {} } namespace N3 { using A = N1.N2.A; class B: A {} }A névtérben lévő tagdeklarációkon belül a névtér egy aliasa,
N3így azAosztályN1.N2.Aaz osztálybólN3.BszármazikN1.N2.A. Ugyanezt a hatást úgy érheti el, hogy létrehoz egy aliastRa következőhözN1.N2, majd hivatkozikR.Ará:namespace N3 { using R = N1.N2; class B : R.A {} }záró példa
A extern_alias_directive tartalmazó összeállítási egységben vagy névtértörzsben lévő irányelvek, globális attribútumok és tagdeklarációk használatával a extern_alias_directive által bevezetett azonosító használható a társított névtérre való hivatkozáshoz.
Példa: Például:
namespace N1 { extern alias N2; class B : N2::A {} }A névtér tagdeklarációiban
N1a fenti névtér egy olyan névtér aliasa,N2amelynek definíciója külső a program forráskódjában. Az osztályN1.Baz osztálybólN2.Aszármazik. Ugyanezt a hatást úgy érheti el, hogy létrehoz egy aliastAa következőhözN2.A, majd hivatkozikArá:namespace N1 { extern alias N2; using A = N2::A; class B : A {} }záró példa
Egy extern_alias_directive vagy using_alias_directive elérhetővé tesz egy aliast egy adott összeállítási egységben vagy névtértörzsben, de nem járul hozzá új tagokhoz az alapul szolgáló deklarációs térhez. Más szóval az alias-irányelv nem tranzitív, hanem csak a fordítási egységre vagy névtértörzsre van hatással, amelyben ez történik.
Példa: Az alábbi kódban
namespace N3 { extern alias R1; using R2 = N1.N2; } namespace N3 { class B : R1::A, R2.I {} // Error, R1 and R2 unknown }az alias-irányelvek hatókörei, amelyek csak abban a névtértörzsben lévő tagdeklarációkra terjednek ki
R1R2, amelyben azok szerepelnek, ígyR1R2nem szerepelnek a második névtér-deklarációban. Ha azonban az alias-irányelveket a fordítási egységben helyezi el, az alias mindkét névtér-deklarációban elérhetővé válik:extern alias R1; using R2 = N1.N2; namespace N3 { class B : R1::A, R2.I {} } namespace N3 { class C : R1::A, R2.I {} }záró példa
Egy compilation_unit vagy namespace_body minden extern_alias_directive vagy using_alias_directive a közvetlenül az compilation_unit vagy namespace_body tartalmazó alias deklarációs térbe (7.3. §) ad nevet. Az alias-irányelv azonosítójának egyedinek kell lennie a megfelelő alias-deklarációs területen belül. Az aliasazonosítónak nem kell egyedinek lennie a globális deklarációs térben vagy a megfelelő névtér deklarációs területén belül.
Example:
extern alias X; extern alias Y; using X = N1.N2; // Error: alias X already exists class Y {} // OkA névvel ellátott
Xalias használata hibát okoz, mivel már van egy alias neveXugyanabban a fordítási egységben. A névvel ellátottYosztály nem ütközik a névvel elnevezettYextern aliassal, mivel ezek a nevek különböző deklarációs szóközökhöz vannak hozzáadva. Az előbbi hozzáadódik a globális deklarációs térhez, az utóbbi pedig a fordítási egység alias deklarációs területéhez.Ha egy aliasnév megegyezik egy névtér egy tagjának nevével, a névtér használatát megfelelően kell minősíteni:
namespace N1.N2 { class B {} } namespace N3 { class A {} class B : A {} } namespace N3 { using A = N1.N2; using B = N1.N2.B; class W : B {} // Error: B is ambiguous class X : A.B {} // Error: A is ambiguous class Y : A::B {} // Ok: uses N1.N2.B class Z : N3.B {} // Ok: uses N3.B }A második névtértörzsben
N3az eredmények nem minősített használataBhibát eredményez, mivelN3tartalmaz egy tagot,Bés a névtér törzsét, amely szintén névvelBrendelkező aliast deklarál; hasonlóképpen a következőhözA: . Az osztályN3.Bhivatkozásként vagyN3.Bnéven is hivatkozhatglobal::N3.B. Az aliasAegy minősített alias-tagban (14.8. §) használható, példáulA::B. Az aliasBlényegében haszontalan. Nem használható qualified_alias_member , mivel csak névtér-aliasok használhatók qualified_alias_member ésBaliasok egy típusban.záró példa
A normál tagokhoz hasonlóan a alias_directives által bevezetett neveket is elrejtik a hasonló nevű tagok a beágyazott hatókörökben.
Példa: Az alábbi kódban
using R = N1.N2; namespace N3 { class R {} class B: R.A {} // Error, R has no member A }a deklarációban szereplő
R.Ahivatkozás fordítási időt eredményez, mertBnemRN3.R.N1.N2záró példa
Az extern_alias_directiveírási sorrendjének nincs jelentősége. Hasonlóképpen, az using_alias_directiveírási sorrendjének nincs jelentősége, de minden using_alias_directives ugyanazon összeállítási egységben vagy névtértörzsben lévő összes extern_alias_directiveután kell érkeznie. A using_alias_directive által hivatkozott namespace_or_type_name felbontását nem befolyásolja az using_alias_directivevagy afordítási egységet vagy névtér törzsét közvetlenül tartalmazó using_directive, de az közvetlenül tartalmazó összeállítási egység vagy névtér törzsében lévő extern_alias_directives-ek is érinthetik. Más szóval egy using_alias_directive namespace_or_type_name úgy oldják fel, mintha az azonnal tartalmazó összeállítási egység vagy névtértörzs nem using_directivevolna, de a megfelelő extern_alias_directives készlettel rendelkezik.
Példa: Az alábbi kódban
namespace N1.N2 {} namespace N3 { extern alias X; using R1 = X::N; // OK using R2 = N1; // OK using R3 = N1.N2; // OK using R4 = R2.N2; // Error, R2 unknown }az utolsó using_alias_directive fordítási időt érintő hibát eredményez, mert az előző using_alias_directive nem érinti. Az első using_alias_directive nem eredményez hibát, mivel az X extern alias hatóköre tartalmazza a using_alias_directive.
záró példa
A using_alias_directive bármilyen névtérhez vagy típushoz létrehozhat aliast, beleértve a névteret, amelyen belül megjelenik, valamint bármely névteret vagy típust, amely az adott névtérbe van ágyazva.
A névtér vagy a típus aliason keresztüli elérése pontosan ugyanazt az eredményt eredményezi, mint az adott névtér elérése vagy a deklarált név alapján történő beírás.
Példa: Adott
namespace N1.N2 { class A {} } namespace N3 { using R1 = N1; using R2 = N1.N2; class B { N1.N2.A a; // refers to N1.N2.A R1.N2.A b; // refers to N1.N2.A R2.A c; // refers to N1.N2.A } }a nevek
N1.N2.A,R1.N2.AésR2.Aegyenértékűek, és mind arra az osztálydeklarációra hivatkoznak , amelynek teljes neveN1.N2.A.záró példa
Bár a részleges típus minden része (15.2.7. §) ugyanabban a névtérben van deklarálva, a részek általában különböző névtér-deklarációkban vannak megírva. Így minden résznél különböző extern_alias_directiveés using_directivelehet jelen. Az egyszerű nevek (12.8.4.§) egy részen belüli értelmezésekor csak a névtértestek és az azt tartalmazó összeállítási egység extern_alias_directiveés using_directives-jét kell figyelembe venni. Ez azt eredményezheti, hogy ugyanaz az azonosító eltérő jelentéssel rendelkezik a különböző részekben.
Example:
namespace N { using List = System.Collections.ArrayList; partial class A { List x; // x has type System.Collections.ArrayList } } namespace N { using List = Widgets.LinkedList; partial class A { List y; // y has type Widgets.LinkedList } }záró példa
Az aliasok használatával zárt, konstruktált típust nevezhet el, de nem nevezhet el kötetlen általános típusdeklarációt típusargumentumok megadása nélkül.
Example:
namespace N1 { class A<T> { class B {} } } namespace N2 { using W = N1.A; // Error, cannot name unbound generic type using X = N1.A.B; // Error, cannot name unbound generic type using Y = N1.A<int>; // Ok, can name closed constructed type using Z<T> = N1.A<T>; // Error, using alias cannot have type parameters }záró példa
14.5.3 Névtér-irányelvek használata
Egy using_namespace_directive importálja a névtérben található típusokat az azonnal belefoglalt összeállítási egységbe vagy névtértörzsbe, így az egyes típusok azonosítója minősítés nélkül használható.
using_namespace_directive
: 'using' namespace_name ';'
;
A using_namespace_directive tartalmazó összeállítási egységben vagy névtértörzsben lévő tagdeklarációkban a megadott névtérben található típusok közvetlenül hivatkozhatók.
Example:
namespace N1.N2 { class A {} } namespace N3 { using N1.N2; class B : A {} }A névtér tagdeklarációiban a névtérben
N3lévő tag típusú tagokN1.N2közvetlenül elérhetők, így az osztályN3.Baz osztálybólN1.N2.Aszármazik.záró példa
Egy using_namespace_directive importálja a megadott névtérben található típusokat, de nem importál beágyazott névtereket.
Példa: Az alábbi kódban
namespace N1.N2 { class A {} } namespace N3 { using N1; class B : N2.A {} // Error, N2 unknown }a using_namespace_directive importálja a benne található
N1típusokat, de a beágyazottN1névterek nem. Így az eredmények deklarációjábanN2.Aszereplő hivatkozásBfordítási idejű hibába ütközik, mivel egyetlen tag sem szerepelN2a hatókörben.záró példa
A using_alias_directive ellentétben a using_namespace_directive olyan típusokat importálhatnak, amelyek azonosítói már definiálva vannak az összeállítási egység vagy a névtér törzsében. A using_namespace_directive által importált neveket valójában a hasonló nevű tagok rejtik el az összeállítási egység vagy névtér törzsében.
Example:
namespace N1.N2 { class A {} class B {} } namespace N3 { using N1.N2; class A {} }Itt a névtérben lévő tagdeklarációkon belül nem
N3a névtérre, hanemAa névtérreN3.AhivatkozikN1.N2.A.záró példa
Mivel a nevek nem egyértelműk, ha egynél több importált névtér ugyanazt a típusnevet használja, a using_alias_directive hasznos lehet a hivatkozás egyértelműsítése.
Példa: Az alábbi kódban
namespace N1 { class A {} } namespace N2 { class A {} } namespace N3 { using N1; using N2; class B : A {} // Error, A is ambiguous }és
N1tartalmaz egy tagotN2, és mivelAmindkét importálást importálja, a hivatkozásN3Afordítási időt érintőN3hiba. Ebben az esetben az ütközés a hivatkozásAminősítésével vagy egy adottAbevezetésével oldható meg . Például:namespace N3 { using N1; using N2; using A = N1.A; class B : A {} // A means N1.A }záró példa
Továbbá, ha az using_namespace_directives vagy using_static_directiveáltal importált több névtér vagy típus ugyanabban a fordítási egységben vagy névtértörzsben azonos névvel tartalmaz típusokat vagy tagokat, akkor az adott névre simple_name való hivatkozások nem egyértelműnek minősülnek.
Example:
namespace N1 { class A {} } class C { public static int A; } namespace N2 { using N1; using static C; class B { void M() { A a = new A(); // Ok, A is unambiguous as a type-name A.Equals(2); // Error, A is ambiguous as a simple-name } } }
N1tartalmaz egy típustagotA, ésCegy statikus mezőtAtartalmaz, és mivelN2mindkettőt importálja,Aa simple_name hivatkozás nem egyértelmű, és fordítási időhiba.záró példa
A using_alias_directive-hez hasonlóan a using_namespace_directive sem járul hozzá új tagokhoz a fordítási egység vagy névtér mögöttes deklarációs teréhez, hanem csak a fordítási egységre vagy névtértörzsre van hatással, amelyben megjelenik.
A using_namespace_directive által hivatkozott namespace_name a using_alias_directive által hivatkozott namespace_or_type_name hasonlóan oldja fel. Így using_namespace_directives ugyanabban a fordítási egységben vagy névtér törzsben nincs hatással egymásra, és bármilyen sorrendben írható.
14.5.4 Statikus irányelvek használata
A using_static_directive közvetlenül a típusdeklarációban szereplő beágyazott típusokat és statikus tagokat importálja az azonnali összeállítási egységbe vagy névtértörzsbe, lehetővé téve az egyes tagok és típusok azonosítójának minősítés nélküli használatát.
using_static_directive
: 'using' 'static' type_name ';'
;
A using_static_directive tartalmazó összeállítási egységben vagy névtértörzsben található tagdeklarációkban közvetlenül hivatkozhat az adott típus deklarációjában közvetlenül a beágyazott típusok és statikus tagok (a bővítménymetelyek kivételével).
Example:
namespace N1 { class A { public class B {} public static B M() => new B(); } } namespace N2 { using static N1.A; class C { void N() { B b = M(); } } }Az előző kódban a névtérben lévő tagdeklarációkban
N2a statikus tagok és a beágyazott típusokN1.Aközvetlenül elérhetők, így a metódusNhivatkozni tud mind a tagokra, mind aBMtagokraN1.A.záró példa
A using_static_directive nem importálja közvetlenül statikus metódusként a bővítménymetódusokat, hanem elérhetővé teszi őket a bővítménymetódus-meghíváshoz (12.8.10.3. §).
Example:
namespace N1 { static class A { public static void M(this string s){} } } namespace N2 { using static N1.A; class B { void N() { M("A"); // Error, M unknown "B".M(); // Ok, M known as extension method N1.A.M("C"); // Ok, fully qualified } } }a using_static_directive importálja a bővítménymetódust
MN1.A, de csak bővítménymetódusként. Így az első hivatkozásMaz eredmények törzsébenB.Nfordítási idő hibába ütközik, mivel egyetlen tag sem szerepelMa hatókörben.záró példa
A using_static_directive csak az adott típusban közvetlenül deklarált tagokat és típusokat importálja, az alaposztályokban deklarált tagokat és típusokat nem.
Example:
namespace N1 { class A { public static void M(string s){} } class B : A { public static void M2(string s){} } } namespace N2 { using static N1.B; class C { void N() { M2("B"); // OK, calls B.M2 M("C"); // Error. M unknown } } }a using_static_directive importálja a benne foglalt
M2metódustN1.B, de nem importálja a benne foglalt metódustMN1.A. Így az eredmények törzsébenMlévő hivatkozásC.Nfordítási idő típusú hibába ütközik, mivel egyetlen tag sem szerepelMa hatókörben. A fejlesztőknek hozzá kell adni egy másodikusing staticirányelvet, amely meghatározza, hogy a metódusokatN1.Ais importálni kell.záró példa
A több using_namespace_directives és using_static_directives közötti kétértelműségeket a 14.5.3.
14.6 Névtértag-deklarációk
A namespace_member_declarationnamespace_declaration (14.3. §) vagy type_declaration (14.7. §).
namespace_member_declaration
: namespace_declaration
| type_declaration
;
A fordítási egység vagy a névtértörzs tartalmazhat namespace_member_declarations-t, és ezek a deklarációk új tagokat adnak hozzá az azt tartalmazó összeállítási egység vagy névtértörzs mögöttes deklarációs területéhez.
14.7 Típusdeklarációk
A type_declarationclass_declaration (15.2.§), struct_declaration (16.2.§), interface_declaration (19.2.§), enum_declaration (20.2. §) vagy delegate_declaration (21.2. §).
type_declaration
: class_declaration
| struct_declaration
| interface_declaration
| enum_declaration
| delegate_declaration
;
A type_declaration egy összeállítási egység legfelső szintű deklarációjaként vagy tagdeklarációként is előfordulhat egy névtérben, osztályban vagy szerkezetben.
Ha egy típus T típusdeklarációja legfelső szintű deklarációként történik egy fordítási egységben, a típusdeklaráció teljes neve (7.8.3. §) megegyezik a deklaráció nem minősített nevével (7.8.2. §). Ha egy típus T típusdeklarációja névtérben, osztályban vagy strukturált deklarációban történik, a típusdeklaráció teljes neve (S.N), ahol S a névtér, osztály vagy szerkezet deklaráció teljes neve, és N a deklaráció nem minősített neve.
Az osztályon, interfészen vagy szerkezeten belül deklarált típusokat beágyazott típusnak nevezzük (15.3.9. §).
A megengedett hozzáférési módosítók és a típusdeklaráció alapértelmezett hozzáférése attól függ, hogy milyen környezetben történik a deklaráció (7.5.2. §):
- A fordítási egységekben vagy névterekben deklarált típusok rendelkezhetnek
publicvagyinternalérhetők el. Az alapértelmezett ainternalhozzáférés. - Az osztályokban deklarált típusok rendelkezhetnek
public,protected internal,protected,private protected,internalvagyprivatehozzáféréssel. Az alapértelmezett aprivatehozzáférés. - A szerkezetekben deklarált típusok rendelkezhetnek
publichozzáférésselinternalvagyprivatehozzáféréssel. Az alapértelmezett aprivatehozzáférés.
14.8 Minősített aliastag
14.8.1 Általános
A lehetővé teszi annak biztosítását, hogy a típusnév-kereséseket ne befolyásolja az új típusok és tagok bevezetése. A névtér alias-minősítője mindig két, bal és jobb oldali azonosítónak nevezett azonosító között jelenik meg. A normál . minősítőtől eltérően a minősítő bal oldali azonosítója :: csak externként vagy alias használatával kereshető meg.
A qualified_alias_member explicit hozzáférést biztosít a globális névtérhez, valamint a más entitások által esetleg rejtett aliasok kiirtásához vagy használatához.
qualified_alias_member
: identifier '::' identifier type_argument_list?
;
A qualified_alias_memberhasználható namespace_or_type_name (7.8.§) vagy bal operandusként egy member_access (12.8.7. §).
A qualified_alias_member két azonosítóból állnak, amelyeket bal és jobb oldali azonosítónak nevezünk, amelyeket a :: jogkivonat jelöl, és opcionálisan egy type_argument_list követ. Ha a bal oldali azonosító globális, akkor a globális névtér a jobb oldali azonosítót keresi. Bármely más bal oldali azonosító esetén az azonosítót külsőként vagy aliasként kell keresni (14.4. és14.5.2. §). Fordítási időhiba akkor fordul elő, ha nincs ilyen alias, vagy az alias egy típusra hivatkozik. Ha az alias egy névtérre hivatkozik, akkor a névtér a jobb oldali azonosítót keresi.
A qualified_alias_member két űrlap egyikével rendelkezik:
-
N::I<A₁, ..., Aₑ>, aholNésIképviseli az azonosítókat, és<A₁, ..., Aₑ>egy típusargumentumlista. (emindig legalább egy.) -
N::I, az azonosítók helyétNésIjelölését. (Ebben az esetbenenullának számít.)
Ezzel a jelöléssel egy qualified_alias_member jelentését a következőképpen határozzuk meg:
- Ha
Naz azonosítóglobal, akkor a globális névtér a következőreIkeres:- Ha a globális névtér egy névteret
Itartalmaz, ésenulla, akkor a qualified_alias_member erre a névtérre hivatkozik. - Ellenkező esetben, ha a globális névtér nem általános típusú nevet
Itartalmaz, ésenulla, akkor a qualified_alias_member erre a típusra hivatkozik. - Ellenkező esetben, ha a globális névtér tartalmaz egy típusparaméterekkel rendelkező
Itípuste, akkor a qualified_alias_member az adott típusargumentumokkal létrehozott típusra hivatkozik. - Ellenkező esetben a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.
- Ha a globális névtér egy névteret
- Ellenkező esetben a qualified_alias_member (ha van ilyen) közvetlenül tartalmazó névtér-deklarációval (14.3. §) kezdve az egyes magában foglaló névtérdeklarációval (ha van ilyen), és a qualified_alias_member tartalmazó fordítási egységgel végződik, a következő lépések lesznek kiértékelve, amíg egy entitás nem található:
- Ha a névtér-deklaráció vagy fordítási egység tartalmaz egy olyan using_alias_directive , amely egy típushoz társítja az N-t, akkor a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.
- Ellenkező esetben, ha a névtér deklarációja vagy fordítási egysége egy névtérhez társított
Ntartalmaz, akkor:- Ha a
Ntársított névtér egyInevű névteret tartalmaz, ésenulla, akkor a qualified_alias_member erre a névtérre hivatkozik. - Ellenkező esetben, ha a
Ntársított névtér egy nem általános típusú,Inevű típust tartalmaz, ésenulla, akkor a qualified_alias_member erre a típusra hivatkozik. - Ellenkező esetben, ha a
Ntársított névtér tartalmaz egyInevű típust, amelyetípusparaméterekkel rendelkezik, akkor a qualified_alias_member az adott típusargumentumokkal létrehozott típusra hivatkozik. - Ellenkező esetben a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.
- Ha a
- Ellenkező esetben a qualified_alias_member nincs definiálva, és fordítási időhiba lép fel.
Példa: A kódban:
using S = System.Net.Sockets; class A { public static int x; } class C { public void F(int A, object S) { // Use global::A.x instead of A.x global::A.x += A; // Use S::Socket instead of S.Socket S::Socket s = S as S::Socket; } }az osztályra
Ahivatkozikglobal::A, a típusSystem.Net.Sockets.Socketpedig a következőreS::Sockethivatkozik: . A használatA.xésS.Socketahelyett fordítási időt eredményezett volna, mertASaz a paraméterekre lett volna megoldva.záró példa
Megjegyzés: Az azonosítónak
globalcsak akkor van különleges jelentése, ha egy qualified_alias_name bal oldali azonosítójaként használják. Ez nem egy kulcsszó, és maga nem alias; környezetfüggő kulcsszó (6.4.4. §). A kódban:class A { } class C { global.A x; // Error: global is not defined global::A y; // Valid: References A in the global namespace }fordítási
global.Aidő hibát okoz, mivel a hatókörben nincs elnevezettglobalentitás. Ha egy globális nevű entitás hatókörben lenne, akkorglobalazglobal.Aadott entitásra lett volna feloldva.Ha egy qualified_alias_member bal oldali azonosítójaként használ
global, az mindig keres aglobalnévtérben, még akkor is, ha van egy alias neve.globalA kódban:using global = MyGlobalTypes; class A { } class C { global.A x; // Valid: References MyGlobalTypes.A global::A y; // Valid: References A in the global namespace }
global.AMyGlobalTypes.Aa globális névtérben lévő osztályraglobal::Aoldja fel ésAoldja fel a feloldásokat.végjegyzet
14.8.2 Az aliasok egyedisége
Minden fordítási egység és névtér törzse külön deklarációs térrel rendelkezik a felesleges aliasok és aliasok használatához. Így míg az extern alias vagy az alias használata egyedinek kell lennie az extern aliasok halmazán belül, és a fordítási egységet vagy névtér törzsét tartalmazó közvetlenül deklarált aliasokat használja, az aliasok csak a típussal vagy névtérrel azonos nevet kaphatnak, feltéve, hogy csak a :: minősítővel használják.
Példa: Az alábbiakban:
namespace N { public class A {} public class B {} } namespace N { using A = System.IO; class X { A.Stream s1; // Error, A is ambiguous A::Stream s2; // Ok } }a névnek
Akét lehetséges jelentése van a második névtér törzsében, mivel az osztályAés a használó aliasAis hatókörben van. Ezért a minősített névAhasználataA.Streamnem egyértelmű, és fordítási idő hibát okoz. A minősítő használataA::azonban nem hiba, mertAcsak névtér-aliasként jelenik meg.záró példa
ECMA C# draft specification