Aracılığıyla paylaş


14 Ad Alanı

14.1 Genel

C# programları ad alanları kullanılarak düzenlenir. Ad alanları hem bir program için "iç" kuruluş sistemi olarak hem de "dış" kuruluş sistemi olarak kullanılır. Bu, diğer programlara sunulan program öğelerini sunmanın bir yoludur.

Ad alanlarının kullanımını kolaylaştırmak için kullanım yönergeleri (§14.5) sağlanır.

14.2 Derleme birimleri

compilation_unit sıfır veya daha fazla extern_alias_directiveve ardından sıfır veya daha fazla using_directiveve ardından sıfır veya bir global_attributes ve ardından sıfır veya daha fazla namespace_member_declarationoluşur. compilation_unit, girişin genel yapısını tanımlar.

compilation_unit
    : extern_alias_directive* using_directive* global_attributes?
      namespace_member_declaration*
    ;

C# programı bir veya daha fazla derleme biriminden oluşur. Bir C# programı derlendiğinde, tüm derleme birimleri birlikte işlenir. Bu nedenle, derleme birimleri birbirine, muhtemelen dairesel bir şekilde bağımlı olabilir.

Derleme biriminin extern_alias_directive, bu derleme biriminin using_directive, global_attributes ve namespace_member_declaration'lerinietkiler, ancak diğer derleme birimleri üzerinde hiçbir etkisi yoktur.

Derleme biriminin using_directive, bu derleme biriminin global_attributes ve namespace_member_declaration'lerinietkiler, ancak diğer derleme birimlerini etkilemez.

Derleme biriminin global_attributes (§23.3), hedef derleme ve modül için özniteliklerin belirtimine izin verir. Derlemeler ve modüller, türler için fiziksel kapsayıcılar olarak görev görür. Bir derleme, fiziksel olarak birbirinden ayrı birkaç modülden oluşabilir.

Bir programın her derleme biriminin namespace_member_declaration, üyeleri genel ad alanı adı verilen tek bir bildirim alanına katkıda bulunur.

Example:

// File A.cs:
class A {}
// File B.cs:
class B {}

İki derleme birimi, tek bir genel ad alanına katkıda bulunur ve bu durumda tam adı A ve Bolan iki sınıfı bildirir. İki derleme birimi aynı bildirim alanına katkıda bulunduğundan, her biri aynı ada sahip bir üye bildirimi içeriyorsa hata olurdu.

son örnek

14.3 Ad alanı bildirimleri

namespace_declaration anahtar sözcük ad alanı, ardından ad alanı adı ve gövdesi, isteğe bağlı olarak noktalı virgülden oluşur.

namespace_declaration
    : 'namespace' qualified_identifier namespace_body ';'?
    ;

qualified_identifier
    : identifier ('.' identifier)*
    ;

namespace_body
    : '{' extern_alias_directive* using_directive*
      namespace_member_declaration* '}'
    ;

namespace_declaration, bir compilation_unit en üst düzey bildirim olarak veya başka birnamespace_declaration içinde üye bildirimi olarak oluşabilir. bir namespace_declaration bir compilation_unit en üst düzey bildirim olarak gerçekleştiğinde, ad alanı genel ad alanının bir üyesi olur. Başka bir namespace_declaration içinde bir namespace_declaration oluştuğunda, iç ad alanı dış ad alanının bir üyesi olur. Her iki durumda da, bir ad alanının adı, içeren ad alanı içinde benzersiz olmalıdır.

Ad alanları örtük olarak public bulunur ve ad alanı bildirimi herhangi bir erişim değiştirici içeremez.

bir namespace_body içinde, isteğe bağlı using_directivediğer ad alanlarının, türlerin ve üyelerin adlarını içeri aktararak bunlara nitelenmiş adlar yerine doğrudan başvurulmasına olanak sağlar. İsteğe bağlı namespace_member_declarationad alanının bildirim alanına üye ekler. Tüm using_directiveüye beyanlarından önce görünecektir.

bir namespace_declaration qualified_identifier tek bir tanımlayıcı veya "." belirteçlerle ayrılmış bir tanımlayıcı dizisi olabilir. İkinci form, bir programın birkaç ad alanı bildirimini sözcük temelli olarak iç içe geçirmeden iç içe bir ad alanı tanımlamasına izin verir.

Example:

namespace N1.N2
{
    class A {}
    class B {}
}

ile eş değer

namespace N1
{
    namespace N2
    {
        class A {}
        class B {}
    }
}

son örnek

Ad alanları açık uçlu olur ve aynı tam ada (§7.8.3) sahip iki ad alanı bildirimi aynı bildirim alanına (§7.3) katkıda bulunur.

Örnek: Aşağıdaki kodda

namespace N1.N2
{
    class A {}
}

namespace N1.N2
{
    class B {}
}

yukarıdaki iki ad alanı bildirimi aynı bildirim alanına katkıda bulunur ve bu durumda tam ad N1.N2.AN1.N2.Bve ile iki sınıf bildirmektedir. İki bildirim aynı bildirim alanına katkıda bulunduğundan, her biri aynı ada sahip bir üye bildirimi içeriyorsa hata olurdu.

son örnek

14.4 Extern diğer ad yönergeleri

extern_alias_directive, ad alanı için diğer ad görevi görecek bir tanımlayıcı tanıtır. Diğer ad alanının belirtimi, programın kaynak kodunun dışındadır ve diğer ad alanının iç içe yerleştirilmiş ad alanlarına da uygulanır.

extern_alias_directive
    : 'extern' 'alias' identifier ';'
    ;

Bir extern_alias_directive kapsamı, hemen compilation_unit veya namespace_bodyiçeren using_directive, global_attributes ve namespace_member_declaration'ler üzerinde genişletir.

extern_alias_directive içeren bir derleme birimi veya ad alanı gövdesinde, extern_alias_directive tarafından tanıtılan tanımlayıcı diğer ad alanına başvurmak için kullanılabilir. Tanımlayıcının sözcüğü globalolması bir derleme zamanı hatasıdır.

bir extern_alias_directive tarafından sunulan diğer ad, bir using_alias_directive tarafından tanıtılan diğer adla çok benzerdir. extern_alias_directive veusing_alias_directivehakkında daha ayrıntılı bilgi için bkz. §14.5.2.

alias bağlamsal bir anahtar sözcüktür (§6.4.4) ve yalnızca extern_alias_directive anahtar sözcüğü hemen extern izlediğinde özel bir anlamı vardır.

Bir program, dış tanımı sağlanmayan bir extern diğer adı bildirirse bir hata oluşur.

Örnek: Aşağıdaki program iki extern diğer adı X bildirir ve kullanır ve Ybunların her biri ayrı bir ad alanı hiyerarşisinin kökünü temsil eder:

extern alias X;
extern alias Y;

class Test
{
    X::N.A a;
    X::N.B b1;
    Y::N.B b2;
    Y::N.C c;
}

Program, extern diğer adlarının ve Xvarlıklarını bildirir, ancak diğer adların Y gerçek tanımları programın dışındadır. Aynı adlı N.B sınıflara artık ve X.N.Bveya ad alanı diğer adı niteleyicisi Y.N.B ve X::N.Bkullanılarak olarak Y::N.B başvurulabiliyor. son örnek

14.5 Yönergeleri kullanma

14.5.1 Genel

Using yönergesi, diğer ad alanları içinde tanımlanan ad alanlarının ve türlerin kullanımını kolaylaştırır. Yönergelerin kullanılması , namespace_or_type_name(§7.8) ve simple_name(§12.8.4) ad çözümleme sürecini etkiler, ancak bildirimlerden farklı olarak , using_directive'leriçinde kullanıldıkları derleme birimlerinin veya ad alanlarının temel bildirim alanlarına yeni üyeler eklemez.

using_directive
    : using_alias_directive
    | using_namespace_directive
    | using_static_directive    
    ;

bir using_alias_directive (§14.5.2), ad alanı veya tür için bir diğer ad adı tanıtır.

using_namespace_directive (§14.5.3), ad alanının tür üyelerini içeri aktarır.

bir using_static_directive (§14.5.4), iç içe türleri ve bir türün statik üyelerini içeri aktarır.

Bir using_directive kapsamı, derleme birimini veya ad alanı gövdesini hemen içeren namespace_member_declarations genişletir. Bir using_directive kapsamı özellikle eş using_directive'leriniiçermez. Bu nedenle, eş using_directive'lerbirbirini etkilemez ve yazılma sırası önemsizdir. Buna karşılık, bir extern_alias_directive kapsamı aynı derleme biriminde veya ad alanı gövdesinde tanımlanan using_directive'leriiçerir.

14.5.2 Diğer ad yönergelerini kullanma

bir using_alias_directive, hemen kapsayan derleme birimi veya ad alanı gövdesi içinde bir ad alanı veya tür için diğer ad görevi görecek bir tanımlayıcı tanıtır.

using_alias_directive
    : 'using' identifier '=' namespace_or_type_name ';'
    ;

Using_alias_directive içeren bir derleme birimi veya ad alanı gövdesindeki genel öznitelikler ve üye bildirimleri içinde,using_alias_directive tarafından tanıtılan tanımlayıcı, verilen ad alanına veya türe başvurmak için kullanılabilir.

Example:

namespace N1.N2
{
    class A {}
}
namespace N3
{
    using A = N1.N2.A;

    class B: A {}
}

Yukarıda, ad alanında üye bildirimleri içinde N3 , A için N1.N2.Abir diğer addır ve bu nedenle sınıfı N3.B sınıfından N1.N2.Atüretilir. Aynı etki, için R bir diğer ad N1.N2 oluşturup öğesine başvurarak R.Aelde edilebilir:

namespace N3
{
    using R = N1.N2;

    class B : R.A {}
}

son örnek

Extern_alias_directive içeren bir derleme birimi veya ad alanı gövdesindeki kullanım yönergeleri, genel öznitelikler ve üye bildirimleri içinde, extern_alias_directive tarafından tanıtılan tanımlayıcı ilişkili ad alanına başvurmak için kullanılabilir.

Örnek: Örneğin:

namespace N1
{
    extern alias N2;

    class B : N2::A {}
}

Yukarıda, ad alanında üye bildirimleri içinde N1 , N2 tanımı programın kaynak kodunun dışında olan bazı ad alanının diğer adıdır. sınıfı N1.B sınıfından N2.Atüretilir. Aynı etki, için A bir diğer ad N2.A oluşturup öğesine başvurarak Aelde edilebilir:

namespace N1
{
    extern alias N2;

    using A = N2::A;

    class B : A {}
}

son örnek

extern_alias_directive veya using_alias_directive, bir diğer adı belirli bir derleme birimi veya ad alanı gövdesinde kullanılabilir hale getirir, ancak temel alınan bildirim alanına yeni üye eklemez. Başka bir deyişle, diğer ad yönergesi geçişli değildir, bunun yerine yalnızca oluştuğu derleme birimini veya ad alanı gövdesini etkiler.

Örnek: Aşağıdaki kodda

namespace N3
{
    extern alias R1;

    using R2 = N1.N2;
}

namespace N3
{
    class B : R1::A, R2.I {} // Error, R1 and R2 unknown
}

dahil edildikleri ad alanı gövdesinde üye bildirimlerini tanıtır R1 ve R2 yalnızca genişleten diğer ad yönergelerinin kapsamları, bu nedenle R1 ve R2 ikinci ad alanı bildiriminde bilinmez. Ancak, diğer ad yönergelerini içeren derleme birimine yerleştirmek, diğer adın her iki ad alanı bildiriminde de kullanılabilir olmasına neden olur:

extern alias R1;

using R2 = N1.N2;

namespace N3
{
    class B : R1::A, R2.I {}
}

namespace N3
{
    class C : R1::A, R2.I {}
}

son örnek

Bir compilation_unit veya namespace_body her extern_alias_directive veya using_alias_directive, hemen kapsayan compilation_unit veyanamespace_body diğer ad bildirim alanına (§7.3) bir ad ekler. Diğer ad yönergesinin tanımlayıcısı ilgili diğer ad bildirim alanında benzersiz olmalıdır. Diğer ad tanımlayıcısı, genel bildirim alanında veya ilgili ad alanının bildirim alanında benzersiz olmamalıdır.

Example:

extern alias X;
extern alias Y;

using X = N1.N2; // Error: alias X already exists

class Y {} // Ok

adlı X diğer ad, aynı derleme biriminde adlı X bir diğer ad bulunduğundan bir hataya neden olur. Bu adlar ayrı bildirim alanlarına eklendiğinden, adlı Y sınıf adlı Y extern diğer adıyla çakışmaz. İlki genel bildirim alanına, ikincisi de bu derleme biriminin diğer ad bildirim alanına eklenir.

Bir diğer ad alanı adı, ad alanının bir üyesinin adıyla eşleştiğinde, her birinin kullanımı uygun şekilde nitelenmelidir:

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
}

için N3ikinci ad alanı gövdesinde, adlı bir üye B içerdiğinden N3 ve ad alanı gövdesi de adına Bsahip bir diğer ad alanı (aynı şekilde içinB) bildirdiğinden, nitelenmemiş kullanımı hatayla A sonuçlanır. sınıfına N3.B veya N3.Bolarak global::N3.B başvurulabilir. Diğer adA, gibi bir nitelenmiş diğer ad-üyesinde (A::B) kullanılabilir. Diğer ad B temelde işe yaramaz. Bir qualified_alias_member yalnızca ad alanı diğer adları ve bir tür diğer ad alanı kullanılabildiğinden , qualified_alias_memberB kullanılamaz.

son örnek

Normal üyeler gibi, alias_directives tarafından tanıtılan adlar da benzer şekilde adlandırılmış üyeler tarafından iç içe yerleştirilmiş kapsamlarda gizlenir.

Örnek: Aşağıdaki kodda

using R = N1.N2;

namespace N3
{
    class R {}
    class B: R.A {} // Error, R has no member A
}

bildiriminde R.A öğesine yapılan başvuru B derleme zamanı hatasına Rneden olur çünkü N3.R öğesine değilN1.N2, öğesine başvurur.

son örnek

extern_alias_directiveyazıldığı sıranın bir önemi yoktur. Benzer şekilde, using_alias_directiveyazıldığı sıranın bir önemi yoktur, ancak tüm using_alias_directives aynı derleme birimi veya ad alanı gövdesindeki tüm extern_alias_directivesonra gelecektir. Bir using_alias_directive tarafından başvuruda bulunılan namespace_or_type_name çözümlemesi, derleme birimi veya ad alanı gövdesini içeren hemen içindeki using_alias_directive veya diğer using_directive'lerdenetkilenmez, ancak hemen içeren derleme birimi veya ad alanı gövdesindeki extern_alias_directive'lerdenetkilenebilir. Başka bir deyişle, bir using_alias_directive namespace_or_type_name, hemen içeren derleme birimi veya ad alanı gövdesinde using_directiveextern_alias_directive kümesi varmış gibi çözümlenir.

Örnek: Aşağıdaki kodda

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
}

son using_alias_directive , önceki using_alias_directive etkilenmediğinden derleme zamanı hatasıyla sonuçlanır. X dış diğer adının kapsamı using_alias_directive içerdiğinden ilk using_alias_directive hataya neden olmaz.

son örnek

using_alias_directive, içinde göründüğü ad alanı ve bu ad alanı içinde iç içe yerleştirilmiş herhangi bir ad alanı veya tür de dahil olmak üzere herhangi bir ad alanı veya tür için bir diğer ad oluşturabilir.

Ad alanına veya türe bir diğer ad aracılığıyla erişmek, ad alanına veya türüne bildirilen adıyla erişmekle tam olarak aynı sonucu verir.

Örnek: Verilen

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
    }
}

, ve N1.N2.AR1.N2.A adları R2.Aeşdeğerdir ve tümü tam adı olan sınıf bildirimine başvururN1.N2.A.

son örnek

Kısmi türün her parçası (§15.2.7) aynı ad alanı içinde bildirilir, ancak genellikle farklı ad alanı bildirimleri içinde yazılır. Bu nedenle, her bölüm için farklı extern_alias_directiveve using_directivebulunabilir. Bir bölümdeki basit adları (§12.8.4) yorumlarken, ad alanı gövdelerinin ve bu bölümü kapsayan derleme biriminin yalnızca extern_alias_directiveve using_directives'leri dikkate alınır. Bu, aynı tanımlayıcının farklı bölümlerde farklı anlamlara sahip olmasına neden olabilir.

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
    }
}

son örnek

Diğer adların kullanılması kapalı bir yapı türü adlandırabilir, ancak tür bağımsız değişkenleri sağlamadan ilişkisiz genel tür bildirimini adlandıramaz.

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
}

son örnek

14.5.3 Ad alanı yönergelerini kullanma

bir using_namespace_directive, bir ad alanında bulunan türleri hemen kapsayan derleme birimine veya ad alanı gövdesine aktarır ve her türün tanımlayıcısının niteleme olmadan kullanılmasını sağlar.

using_namespace_directive
    : 'using' namespace_name ';'
    ;

Using_namespace_directive içeren bir derleme birimi veya ad alanı gövdesindeki üye bildirimleri içinde, verilen ad alanında yer alan türlere doğrudan başvurulabilir.

Example:

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1.N2;

    class B : A {}
}

Yukarıda, ad alanında üye bildirimleri içinde N3 , türü üyeleri N1.N2 doğrudan kullanılabilir ve bu nedenle sınıfı N3.B sınıfından N1.N2.Atüretilir.

son örnek

bir using_namespace_directive verilen ad alanında bulunan türleri içeri aktarır, ancak özellikle iç içe yerleştirilmiş ad alanlarını içeri aktarmaz.

Örnek: Aşağıdaki kodda

namespace N1.N2
{
    class A {}
}

namespace N3
{
    using N1;
    class B : N2.A {} // Error, N2 unknown
}

using_namespace_directive içinde bulunan N1türleri içeri aktarır, ancak içinde N1iç içe yerleştirilmiş ad alanlarını içeri aktarmaz. Bu nedenle, adlı N2.A hiçbir üye kapsam içinde B olmadığından, bildiriminde başvurusu N2 derleme zamanı hatasıyla sonuçlanır.

son örnek

bir using_alias_directive aksine, bir using_namespace_directive tanımlayıcıları zaten kapsayan derleme birimi veya ad alanı gövdesi içinde tanımlanmış türleri içeri aktarabilir. Aslında, bir using_namespace_directive tarafından içeri aktarılan adlar, kapsayan derleme birimindeki veya ad alanı gövdesindeki benzer adlandırılmış üyeler tarafından gizlenir.

Example:

namespace N1.N2
{
    class A {}
    class B {}
}

namespace N3
{
    using N1.N2;
    class A {}
}

Burada, ad alanında N3 üye bildirimleri içinde A yerine N3.Aöğesine N1.N2.A başvurur.

son örnek

Birden fazla içeri aktarılan ad alanı aynı tür adı sağladığında adlar belirsiz olabileceğinden, using_alias_directive başvuruyu belirsiz hale getirmek için yararlıdır.

Örnek: Aşağıdaki kodda

namespace N1
{
    class A {}
}

namespace N2
{
    class A {}
}

namespace N3
{
    using N1;
    using N2;

    class B : A {} // Error, A is ambiguous
}

hem hem N1 de N2 bir üye Aiçerir ve her ikisini de içeri aktardığından N3 içinde başvuruda AN3 bulunmak bir derleme zamanı hatasıdır. Bu durumda, çakışma , başvurularının Anitelenmesiyle veya belirli bir öğesini seçen bir A tanıtılarak çözülebilir. Örneğin:

namespace N3
{
    using N1;
    using N2;
    using A = N1.A;

    class B : A {} // A means N1.A
}

son örnek

Ayrıca, aynı derleme biriminde veya ad alanı gövdesinde using_namespace_directiveveya using_static_directivetarafından içeri aktarılan birden fazla ad alanı veya tür aynı ada sahip türler veya üyeler içerdiğinde, simple_name olarak bu ada yapılan başvurular belirsiz kabul edilir.

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
        }
    }
}

N1bir tür üyesi Aiçerir ve statik bir alan Ciçerir ve A her ikisini de içeri aktardığındanN2, A olarak başvurmak belirsizdir ve derleme zamanı hatasıdır.

son örnek

bir using_alias_directive gibi, bir using_namespace_directive derleme biriminin veya ad alanının temel bildirim alanına yeni üye eklemez, bunun yerine yalnızca içinde göründüğü derleme birimini veya ad alanı gövdesini etkiler.

bir using_namespace_directive tarafından başvuruda bulunan namespace_name, bir using_alias_directive tarafından başvuruda bulunan namespace_or_type_name aynı şekilde çözümlenir. Bu nedenle, aynı derleme birimi veya ad alanı gövdesindeki using_namespace_directivebirbirini etkilemez ve herhangi bir sırayla yazılabilir.

14.5.4 Statik yönergeleri kullanma

bir using_static_directive, doğrudan bir tür bildiriminde yer alan iç içe türleri ve statik üyeleri hemen kapsayan derleme birimine veya ad alanı gövdesine içeri aktararak her üyenin ve türün tanımlayıcısının nitelik olmadan kullanılmasını sağlar.

using_static_directive
    : 'using' 'static' type_name ';'
    ;

Using_static_directive içeren bir derleme birimi veya ad alanı gövdesindeki üye bildirimleri içinde, doğrudan verilen türün bildiriminde yer alan erişilebilir iç içe türler ve statik üyelere (uzantı yöntemleri dışında) doğrudan başvurulabilir.

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();
        }
    }
}

Yukarıdaki kodda, ad alanında üye bildirimleri içinde N2 statik üyeler ve iç içe türleri N1.A doğrudan kullanılabilir ve bu nedenle yöntemi N hem hem de B üyelerine MN1.Abaşvurabiliyor.

son örnek

using_static_directive özellikle uzantı yöntemlerini doğrudan statik yöntemler olarak içeri aktarmaz, ancak uzantı yöntemi çağırma için kullanılabilir hale getirir (§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
        }
    }
}

using_static_directive içinde bulunan Muzantı yöntemini N1.A içeri aktarır, ancak yalnızca bir uzantı yöntemi olarak içeri aktarır. Bu nedenle, adlı M hiçbir üye kapsam içinde olmadığından gövdesindeki B.N ilk başvurusu M derleme zamanı hatasıyla sonuçlanır.

son örnek

using_static_directive, temel sınıflarda bildirilen üyeleri ve türleri değil, yalnızca doğrudan belirtilen türde bildirilen üyeleri ve türleri içeri aktarır.

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 
        }
    }
}

using_static_directive içinde bulunan M2yöntemini N1.B içeri aktarır, ancak içinde Mbulunan yöntemi N1.A içeri aktarmaz. Bu nedenle, adlı hiçbir üye M kapsam içinde olmadığından, gövdesinde C.N başvurusu M derleme zamanı hatasıyla sonuçlanır. Geliştiricilerin içindeki yöntemlerin de içeri aktarılması gerektiğini belirtmek için ikinci using static bir yönerge eklemesi N1.A gerekir.

son örnek

Birden çok using_namespace_directives ile using_static_directives arasındaki belirsizlikler §14.5.3'te ele alınmaktadır.

14.6 Ad alanı üye bildirimleri

namespace_member_declaration bir namespace_declaration (§14.3) veya type_declaration (§14.7) olur.

namespace_member_declaration
    : namespace_declaration
    | type_declaration
    ;

Derleme birimi veya ad alanı gövdesi namespace_member_declarationiçerebilir ve bu tür bildirimler, derleme birimini veya ad alanı gövdesini içeren temel bildirim alanına yeni üyeler katkıda bulunur.

14.7 Tür bildirimleri

type_declarationclass_declaration (§15.2), struct_declaration (§16.2), interface_declaration (§19.2), enum_declaration (§20.2) veya delegate_declaration (§21.2) şeklindedir.

type_declaration
    : class_declaration
    | struct_declaration
    | interface_declaration
    | enum_declaration
    | delegate_declaration
    ;

type_declaration, bir derleme biriminde en üst düzey bildirim olarak veya ad alanı, sınıf veya yapı içindeki üye bildirimi olarak oluşabilir.

Bir tür T için tür bildirimi bir derleme biriminde en üst düzey bildirim olarak gerçekleştiğinde, tür bildiriminin tam adı (§7.8.3), bildirimin nitelenmemiş adıyla (§7.8.2) aynıdır. Bir tür T için tür bildirimi bir ad alanı, sınıf veya yapı bildirimi içinde gerçekleştiğinde, tür bildiriminin tam adı (S.N), burada S içeren ad alanı, sınıf veya yapı bildiriminin tam adıdır ve N bildirimin nitelenmemiş adıdır.

Sınıf, arabirim veya yapı içinde bildirilen bir tür iç içe geçmiş tür (§15.3.9) olarak adlandırılır.

İzin verilen erişim değiştiricileri ve tür bildirimi için varsayılan erişim, bildirimin gerçekleştiği bağlama bağlıdır (§7.5.2):

  • Derleme birimlerinde veya ad alanları içinde bildirilen türlerin erişimi public veya internal erişimi olabilir. Varsayılan değer erişimdir internal .
  • Sınıflarda bildirilen türlerde , public, protected internal, protected, , private protectedveya internal erişimi olabilirprivate. Varsayılan değer erişimdir private .
  • Yapılarda bildirilen türlerde , publicveya internal erişimi olabilirprivate. Varsayılan değer erişimdir private .

14.8 Nitelenmiş diğer ad üyesi

14.8.1 Genel

Ad , tür adı aramalarının yeni türlerin ve üyelerin tanıtılmasından etkilenmemesini garanti altına almak mümkün kılar. Ad alanı diğer ad niteleyicisi her zaman sol ve sağ tanımlayıcı olarak adlandırılan iki tanımlayıcı arasında görünür. Normal . niteleyicinin aksine, niteleyicinin :: soldaki tanımlayıcısı yalnızca extern olarak veya diğer ad kullanılarak aranılır.

qualified_alias_member, genel ad alanına ve diğer varlıklar tarafından gizlenebilecek diğer adların extern veya kullanımına açık erişim sağlar.

qualified_alias_member
    : identifier '::' identifier type_argument_list?
    ;

qualified_alias_memberbir namespace_or_type_name (§7.8) veya bir member_access sol işlenen olarak kullanılabilir (§12.8.7).

qualified_alias_member, belirtecin ayırdığı ve isteğe bağlı olarak bir :: izlediği sol ve sağ tanımlayıcılar olarak adlandırılan iki tanımlayıcıdan oluşur. Soldaki tanımlayıcı genel olduğunda, genel ad alanı sağ tanımlayıcı için aranılır. Diğer sol tanımlayıcılar için bu tanımlayıcı extern olarak veya diğer ad (§14.4 ve §14.5.2) kullanılarak aranılır. Böyle bir diğer ad yoksa veya diğer ad bir türe başvuruda bulunuyorsa derleme zamanı hatası oluşur. Diğer ad bir ad alanına başvuruda bulunursa, bu ad alanı sağ tanımlayıcı için aranılır.

qualified_alias_member iki biçimden birine sahiptir:

  • N::I<A₁, ..., Aₑ>, burada N ve I tanımlayıcıları temsil eder ve <A₁, ..., Aₑ> bir tür bağımsız değişken listesidir. (e her zaman en az birdir.)
  • N::I, burada N ve I tanımlayıcıları temsil eder. (Bu durumda sıfır e olarak kabul edilir.)

Bu gösterimi kullanarak, bir qualified_alias_member anlamı aşağıdaki gibi belirlenir:

  • tanımlayıcısı Niseglobal, genel ad alanı için Iaranılır:
    • Genel ad alanı adlı I bir ad alanı içeriyorsa ve e sıfırsa, qualified_alias_member bu ad alanına başvurur.
    • Aksi takdirde, genel ad alanı adlı I genel olmayan bir tür içeriyorsa ve e sıfırsa, qualified_alias_member bu türe başvurur.
    • Aksi takdirde, genel ad alanı tür parametrelerine sahip I adlı e bir tür içeriyorsa, qualified_alias_member verilen tür bağımsız değişkenleriyle oluşturduğunuz türe başvurur.
    • Aksi takdirde, qualified_alias_member tanımsız olur ve derleme zamanı hatası oluşur.
  • Aksi takdirde, ad alanı bildirimiyle (§14.3) hemen qualified_alias_member (varsa) içeren, her kapsayan ad alanı bildirimiyle (varsa) devam eden ve qualified_alias_member içeren derleme birimiyle biten ad alanı bildiriminden başlayarak, bir varlık bulunana kadar aşağıdaki adımlar değerlendirilir:
    • Ad alanı bildirimi veya derleme birimi N'yi bir türle ilişkilendiren bir using_alias_directive içeriyorsa , qualified_alias_member tanımsız olur ve derleme zamanı hatası oluşur.
    • Aksi takdirde, ad alanı bildirimi veya derleme birimi bir ad alanıyla ilişkilendiren bir extern_alias_directive veya N içeriyorsa:
      • N ile ilişkilendirilmiş ad alanı I adlı bir ad alanı içeriyorsa ve e sıfırsa, qualified_alias_member bu ad alanına başvurur.
      • Aksi takdirde, N ile ilişkili ad alanı I adlı genel olmayan bir tür içeriyorsa ve e sıfırsa, qualified_alias_member bu türe başvurur.
      • Aksi takdirde, N ile ilişkilendirilmiş ad alanı, I tür parametrelerine sahip e adlı bir tür içeriyorsa, verilen tür bağımsız değişkenleriyle oluşturulmuş olan türe, qualified_alias_member başvurur.
      • Aksi takdirde, qualified_alias_member tanımsız olur ve derleme zamanı hatası oluşur.
  • Aksi takdirde, qualified_alias_member tanımsız olur ve derleme zamanı hatası oluşur.

Örnek: Kodda:

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;
    }
}

sınıfına A ve global::A türüne System.Net.Sockets.Socket ile S::Socketbaşvurulur. ve A.xS.Socket kullanmak derleme zamanı hatalarına neden olurdu çünkü A ve S parametrelerine çözümlenecekti.

son örnek

Not: Tanımlayıcının global yalnızca bir qualified_alias_name sol tanımlayıcısı olarak kullanıldığında özel bir anlamı vardır. Bu bir anahtar sözcük değildir ve kendisi bir diğer ad değildir; bağlamsal anahtar sözcüktür (§6.4.4). Kodda:

class A { }

class C
{
    global.A x; // Error: global is not defined
    global::A y; // Valid: References A in the global namespace
}

kullanmak global.A , kapsamda adlı global bir varlık olmadığından derleme zamanı hatasına neden olur. Global adlı bir varlık kapsam içinde olsaydı, global içinde global.A bu varlığa çözümlenebilirdi.

bir globalqualified_alias_member sol tanımlayıcısı olarak kullanmak, adlı globalbir diğer ad olsa bile ad alanında global her zaman bir aramanın olmasına neden olur. Kodda:

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.A çözümleyip MyGlobalTypes.Aglobal::A genel ad alanında sınıfına A çözümler.

dipnot

14.8.2 Diğer adların benzersizliği

Her derleme birimi ve ad alanı gövdesi, diğer adların ve diğer adların kullanılması için ayrı bir bildirim alanına sahiptir. Bu nedenle, bir extern diğer adının veya diğer adın kullanılması, extern diğer adları kümesi içinde benzersiz olmalıdır ve derleme birimini veya ad alanı gövdesini içeren hemen içinde bildirilen diğer adlar kullanılırken, yalnızca niteleyici ile kullanıldığı sürece bir diğer adın bir tür veya ad alanıyla :: aynı ada sahip olmasına izin verilir.

Örnek: Aşağıdakilerde:

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
    }
}

hem sınıfı A hem de kullanan diğer ad A kapsamı içinde olduğundan, ikinci ad alanı gövdesinde adın A iki olası anlamı vardır. Bu nedenle, nitelenmiş ad A içinde kullanımı A.Stream belirsizdir ve derleme zamanı hatası oluşmasına neden olur. Ancak, yalnızca ad alanı diğer adı olarak arandığından A niteleyici ile :: kullanımı A bir hata değildir.

son örnek