Was sind die Standardzugriffsmodifikatoren in C #?

384

Was ist der Standardzugriffsmodifikator für Klassen, Methoden, Mitglieder, Konstruktoren, Delegaten und Schnittstellen?

Surya sasidhar
quelle

Antworten:

486

Der Standardzugriff für alles in C # ist "der am meisten eingeschränkte Zugriff, den Sie für dieses Mitglied deklarieren können" .

Also zum Beispiel:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}

ist äquivalent zu

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}

Die einzige Ausnahme besteht darin, dass ein Teil einer Eigenschaft (normalerweise der Setter) eingeschränkter ist als die deklarierte Zugänglichkeit der Eigenschaft selbst:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}

Dies ist, was die C # 3.0-Spezifikation zu sagen hat (Abschnitt 3.5.1):

Abhängig vom Kontext, in dem eine Mitgliedererklärung stattfindet, sind nur bestimmte Arten der deklarierten Zugänglichkeit zulässig. Wenn eine Mitgliedsdeklaration keine Zugriffsmodifikatoren enthält, bestimmt der Kontext, in dem die Deklaration stattfindet, die standardmäßig deklarierte Zugänglichkeit.

  • Namespaces haben implizit öffentlich deklarierte Zugänglichkeit. Für Namespace-Deklarationen sind keine Zugriffsmodifikatoren zulässig.
  • In Kompilierungseinheiten oder Namespaces deklarierte Typen können öffentlich oder intern deklariert sein und standardmäßig intern deklariert sein.
  • Klassenmitglieder können eine der fünf Arten der deklarierten Zugänglichkeit haben und standardmäßig die private deklarierte Zugänglichkeit verwenden. (Beachten Sie, dass ein als Mitglied einer Klasse deklarierter Typ eine der fünf Arten der deklarierten Zugänglichkeit haben kann, während ein als Mitglied eines Namespace deklarierter Typ nur öffentliche oder interne deklarierte Zugänglichkeit haben kann.)
  • Strukturmitglieder können öffentlich, intern oder privat deklariert sein und standardmäßig privat deklariert sein, da Strukturen implizit versiegelt sind. Strukturelemente, die in einer Struktur eingeführt wurden (dh nicht von dieser Struktur geerbt wurden), können keine geschützte oder geschützte interne deklarierte Zugänglichkeit haben. (Beachten Sie, dass ein Typ, der als Mitglied einer Struktur deklariert ist, öffentlich, intern oder privat deklariert werden kann, während ein Typ, der als Mitglied eines Namespace deklariert ist, nur öffentlich oder intern deklariert werden kann.)
  • Schnittstellenmitglieder haben implizit öffentlich deklarierte Zugänglichkeit. Für Deklarationen von Schnittstellenmitgliedern sind keine Zugriffsmodifikatoren zulässig.
  • Aufzählungsmitglieder haben implizit öffentlich deklarierte Zugänglichkeit. Für Deklarationen von Aufzählungsmitgliedern sind keine Zugriffsmodifikatoren zulässig.

(Beachten Sie, dass verschachtelte Typen unter die Teile "Klassenmitglieder" oder "Strukturmitglieder" fallen und daher standardmäßig die private Sichtbarkeit verwenden.)

Jon Skeet
quelle
154
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
John Buchanan
quelle
13
Dies macht nicht deutlich, dass eine Klasse, wenn sie auch Mitglied ist (da sie ein verschachtelter Typ ist), standardmäßig privat ist. Außerdem sind Mitglieder einer Schnittstelle und einer Aufzählung immer öffentlich.
Jon Skeet
1
@niry Nein, es ist nicht privat. Es ist öffentlich. Es funktioniert einfach nicht mit einem Schlitz in dem Durchführungstyp bekommen, also , wenn class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();Sie keinen Zugriff Mmit a.M(), aber können Sie darauf zugreifen mit (a as IFoo).M(). (Überprüfen Sie die Spezifikation für weitere Informationen zu den
Einzelheiten
130

Kurze Antwort: Mindestzugriff (vgl. Antwort von Jon Skeet).

Lange Antwort:

Nicht verschachtelte Typen, Aufzählung und delegierte Zugänglichkeiten ( möglicherweise nur interne oder öffentliche Zugänglichkeit )

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | internal  | public, internal

class                | internal  | public, internal

struct               | internal  | public, internal

delegate             | internal  | public, internal

Verschachtelte Zugänglichkeit für Typ und Mitglieder

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | public    | none

class                | private   | All¹

struct               | private   | public, internal, private²

delegate             | private   | All¹

constructor          | private   | All¹

interface member     | public    | none (always implicitly public)

method               | private   | All¹

field                | private   | All¹

user-defined operator| none      | public (must be declared public)

¹ Alle === öffentlich, geschützt, intern, privat, geschützt intern

² Strukturen können nicht von Strukturen oder Klassen erben (obwohl sie Schnittstellen können), daher ist protected kein gültiger Modifikator

Die Zugänglichkeit eines verschachtelten Typs hängt von seiner Zugänglichkeitsdomäne ab, die sowohl von der deklarierten Zugänglichkeit des Mitglieds als auch von der Zugänglichkeitsdomäne des unmittelbar enthaltenden Typs bestimmt wird. Die Eingabehilfendomäne eines verschachtelten Typs darf jedoch die des enthaltenden Typs nicht überschreiten.

Hinweis: CIL hat auch die Bestimmung für geschützt und intern (im Gegensatz zu den vorhandenen geschützten "oder" internen), aber meines Wissens ist dies derzeit nicht für die Verwendung in C # verfügbar.


Sehen:

http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- us / library / cx03xt0t.aspx
(Mann, ich liebe Microsoft URIs ...)

Ben Aston
quelle
12

Schauen Sie sich Access Modifiers an (C # Programmierhandbuch).

Klassen- und Strukturzugänglichkeit

Klassen und Strukturen, die direkt in einem Namespace deklariert sind (dh nicht in anderen Klassen oder Strukturen verschachtelt sind), können entweder öffentlich oder intern sein. Intern ist die Standardeinstellung, wenn kein Zugriffsmodifikator angegeben ist.

Strukturmitglieder, einschließlich verschachtelter Klassen und Strukturen, können als öffentlich, intern oder privat deklariert werden. Klassenmitglieder, einschließlich verschachtelter Klassen und Strukturen, können öffentlich, intern geschützt, geschützt, intern, privat geschützt oder privat sein. Die Zugriffsebene für Klassenmitglieder und Strukturmitglieder, einschließlich verschachtelter Klassen und Strukturen, ist standardmäßig privat. Auf private verschachtelte Typen kann von außerhalb des enthaltenen Typs nicht zugegriffen werden.

Abgeleitete Klassen können nicht besser zugänglich sein als ihre Basistypen. Mit anderen Worten, Sie können keine öffentliche Klasse B haben, die von einer internen Klasse A abgeleitet ist. Wenn dies zulässig wäre, würde dies dazu führen, dass A öffentlich gemacht wird, da alle geschützten oder internen Mitglieder von A von der abgeleiteten Klasse aus zugänglich sind.

Sie können bestimmten anderen Assemblys den Zugriff auf Ihre internen Typen ermöglichen, indem Sie die Option verwenden InternalsVisibleToAttribute. Weitere Informationen finden Sie unter Freundversammlungen.

Zugänglichkeit für Klassen- und Strukturmitglieder

Klassenmitglieder (einschließlich verschachtelter Klassen und Strukturen) können mit jeder der sechs Zugriffsarten deklariert werden. Strukturelemente können nicht als geschützt deklariert werden, da Strukturen keine Vererbung unterstützen.

Normalerweise ist die Zugänglichkeit eines Mitglieds nicht größer als die Zugänglichkeit des Typs, der es enthält. Auf ein öffentliches Mitglied einer internen Klasse kann jedoch möglicherweise von außerhalb der Assembly zugegriffen werden, wenn das Mitglied Schnittstellenmethoden implementiert oder virtuelle Methoden überschreibt, die in einer öffentlichen Basisklasse definiert sind.

Der Typ eines Mitglieds, das ein Feld, eine Eigenschaft oder ein Ereignis ist, muss mindestens so zugänglich sein wie das Mitglied selbst. Ebenso müssen der Rückgabetyp und die Parametertypen eines Mitglieds, das eine Methode, ein Indexer oder ein Delegat ist, mindestens so zugänglich sein wie das Mitglied selbst. Beispielsweise können Sie keine öffentliche Methode M haben, die eine Klasse C zurückgibt, es sei denn, C ist ebenfalls öffentlich. Ebenso können Sie keine geschützte Eigenschaft vom Typ A haben, wenn A als privat deklariert ist.

Benutzerdefinierte Operatoren müssen immer als öffentlich und statisch deklariert werden. Weitere Informationen finden Sie unter Überladen des Bedieners.

Finalizer können keine Eingabehilfenmodifikatoren haben.

Andere Arten

Schnittstellen, die direkt in einem Namespace deklariert sind, können als öffentlich oder intern deklariert werden. Genau wie Klassen und Strukturen verwenden Schnittstellen standardmäßig internen Zugriff. Schnittstellenmitglieder sind immer öffentlich, da der Zweck einer Schnittstelle darin besteht, anderen Typen den Zugriff auf eine Klasse oder Struktur zu ermöglichen. Auf Schnittstellenmitglieder können keine Zugriffsmodifikatoren angewendet werden.

Aufzählungsmitglieder sind immer öffentlich und es können keine Zugriffsmodifikatoren angewendet werden.

Delegaten verhalten sich wie Klassen und Strukturen. Standardmäßig haben sie internen Zugriff, wenn sie direkt in einem Namespace deklariert werden, und privaten Zugriff, wenn sie verschachtelt sind.

Adriaan Stander
quelle
8

Die Klasse ist standardmäßig intern .

  • Klassenmitglieder sind standardmäßig privat .

Die Schnittstelle ist standardmäßig intern .

  • Schnittstellenmitglieder sind standardmäßig öffentlich . (Über Schnittstellen können wir keine Zugänglichkeit für die Mitglieder festlegen.)

    Hinweis: Wenn Sie versuchen, den Mitgliedern der Schnittstelle einen Zugriffsspezifizierer anzugeben, wird ein Kompilierungsfehler angezeigt.

Struct ist standardmäßig intern .

  • Strukturmitglieder sind standardmäßig privat .
Kamala Hanchinal
quelle
5

Ich möchte einen Dokumentationslink hinzufügen. Weitere Details finden Sie hier .

Geben Sie hier die Bildbeschreibung ein

Asif Mushtaq
quelle
1
Klasse ist standardmäßig intern und nicht privat.
Baahubali
1
Wo ich schrieb, ist der Unterricht privat?
Asif Mushtaq
Diese Tabelle ist nur für verschachtelte Typen gültig.
BlueSilver
Die Klasse ist standardmäßig intern und die Klasse im Namespace kann nicht privat sein. Aber Klasse innerhalb einer Klasse (verschachtelte Klasse) kann privat sein
Arun
Der Zugriffsmodifikator der Schnittstelle ist standardmäßig Intern .
Kamala Hanchinal
4

Die einfachste Antwort ist die folgende .....

Alle Mitglieder in C # verwenden immer den standardmäßig MINDEST zugänglichen Modifikator.

Aus diesem Grund sind alle Klassen der obersten Ebene in einer Assembly standardmäßig "intern". Dies bedeutet, dass sie für die Assembly, in der sie sich befinden, öffentlich, aber privat oder vom Zugriff auf externe Assemblys ausgeschlossen sind. Die einzige andere Option für eine Klasse der obersten Ebene ist öffentlich, die leichter zugänglich ist. Für verschachtelte Typen ist alles privat, bis auf einige seltene Ausnahmen wie Mitglieder von Aufzählungen und Schnittstellen, die nur öffentlich sein können. Einige Beispiele. Bei Klassen und Schnittstellen der obersten Ebene sind die Standardeinstellungen:

Klasse Tier wie interne Klasse Tier

Schnittstelle Tier wie öffentliche Schnittstelle Tier

Bei verschachtelten Klassen und Schnittstellen (innerhalb von Typen) sind die Standardeinstellungen:

Klasse Tier wie Privatklasse Tier

Schnittstelle Tier wie private Schnittstelle Tier

Wenn Sie nur davon ausgehen, dass die Standardeinstellung immer die privateste ist, müssen Sie keine Accessoren verwenden, bis Sie die Standardeinstellung ändern müssen. Einfach.

Stokely
quelle
1

Intern ist der Standardmodifikator

Renjucool
quelle
0

Namespace-Ebene: internal

Typstufe: private

Leppie
quelle