it-swarm.com.de

Was ist in C # der Unterschied zwischen öffentlich, privat, geschützt und ohne Zugriffsmodifikator?

Alle meine College-Jahre habe ich public verwendet und möchte den Unterschied zwischen public, private und protected kennen?

Was macht static im Gegensatz zu nichts?

691
MrM

Zugriffsmodifikatoren

Von docs.Microsoft.com

public

Auf den Typ oder das Element kann von jedem anderen Code in derselben Assembly oder einer anderen Assembly zugegriffen werden, die auf ihn verweist.

privat

Auf den Typ oder Member kann nur mit Code in derselben Klasse oder Struktur zugegriffen werden.

geschützt

Auf den Typ oder Member kann nur mit Code in derselben Klasse oder Struktur oder in einer abgeleiteten Klasse zugegriffen werden.

privat geschützt (hinzugefügt in C # 7.2)

Auf den Typ oder Member kann nur mit Code in derselben Klasse oder Struktur oder in einer abgeleiteten Klasse aus derselben Assembly zugegriffen werden, nicht jedoch aus einer anderen Assembly.

intern

Auf den Typ oder das Element kann von jedem Code in derselben Assembly zugegriffen werden, jedoch nicht von einer anderen Assembly.

geschützt intern

Auf den Typ oder Member kann von jedem Code in derselben Assembly oder von jeder abgeleiteten Klasse in einer anderen Assembly zugegriffen werden.

Wenn kein Zugriffsmodifikator festgelegt ist, wird ein Standard-Zugriffsmodifikator verwendet. Es gibt also immer eine Art Zugriffsmodifikator, auch wenn er nicht festgelegt ist.

Statisch

Der statische Modifikator für eine Klasse bedeutet, dass die Klasse nicht instanziiert werden kann und dass alle ihre Mitglieder statisch sind. Ein statisches Element verfügt über eine Version, unabhängig davon, wie viele Instanzen seines umschließenden Typs erstellt wurden.

Eine statische Klasse ist im Grunde dieselbe wie eine nicht statische Klasse, es gibt jedoch einen Unterschied: Eine statische Klasse kann nicht extern instanziiert werden. Mit anderen Worten, Sie können das neue Schlüsselwort nicht zum Erstellen einer Variablen des Klassentyps verwenden. Da es keine Instanzvariable gibt, greifen Sie auf die Mitglieder einer statischen Klasse zu, indem Sie den Klassennamen selbst verwenden.

Es gibt jedoch einen statischer Konstruktor . Jede Klasse kann über eine dieser Klassen verfügen, einschließlich statischer Klassen. Sie können nicht direkt aufgerufen werden und keine Parameter haben (außer Typparametern für die Klasse selbst). Ein statischer Konstruktor wird automatisch aufgerufen, um die Klasse zu initialisieren, bevor die erste Instanz erstellt wird oder auf statische Member verwiesen wird. Sieht aus wie das:

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}

Statische Klassen werden häufig als Services verwendet. Sie können sie folgendermaßen verwenden:

MyStaticClass.ServiceMethod(...);
968
mbillard

Öffentlich - Wenn Sie die Klasse sehen können, können Sie die Methode sehen

Privat - Wenn Sie Teil der Klasse sind, können Sie die Methode sehen, ansonsten nicht.

Geschützt - Wie Privat, plus alle Nachkommen können auch die Methode sehen.

Static (class) - Erinnern Sie sich an die Unterscheidung zwischen "Class" und "Object"? Vergiss das alles. Sie sind die gleichen mit "statisch" ... die Klasse ist die einzige Instanz von sich.

Statisch (Methode) - Wenn Sie diese Methode verwenden, wird ein Referenzrahmen erstellt, der von der tatsächlichen Instanz der Klasse, zu der sie gehört, unabhängig ist.

156
JosephStyons

Eine grafische Übersicht (Zusammenfassung auf den Punkt gebracht)

Visibility

Informationen zu den Standardeinstellungen, wenn Sie keinen Zugriffsmodifikator voranstellen, finden Sie hier:
Standardsichtbarkeit für C # -Klassen und -Mitglieder (Felder, Methoden usw.)?

Nicht verschachtelt

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

Verschachtelt:

nested enum      public
nested interface public
nested class     private
nested struct    private
147
Stefan Steiger

enter image description here

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}
22
Narottam Goyal

In Bezug auf die Frage von Nichts

  • Namespace-Typen sind standardmäßig intern
  • Alle Typenmitglieder, einschließlich verschachtelter Typen, sind standardmäßig privat
22
leppie

Reposting der fantastischen Diagramme von diese Antwort .

Hier sind alle Zugriffsmodifikatoren in Venn-Diagrammen, von einschränkender bis promiskuitiver:

private:
enter image description here

private protected: - hinzugefügt in C # 7.2
enter image description here

internal:
enter image description here

protected:
enter image description here

protected internal:
enter image description here

public:
enter image description here

19
Paul

Hmm.

Siehe hier: Access Modifiers .

In einer Nussschale:

Public gibt der Methode oder dem Typ die vollständige Sichtbarkeit für andere Typen/Klassen.

Private erlaubt nur den Typ, der die private Methode/Variable enthält, den Zugriff auf die private Methode/Variable (beachten Sie, dass verschachtelte Klassen auch Zugriff auf die enthaltenen privaten Methoden/Variablen haben).

Geschützt ist ähnlich wie privat, nur dass abgeleitete Klassen auch auf geschützte Methoden zugreifen können.

"Nothing" ist das Äquivalent von VB.NET zu null. Wenn Sie sich zwar auf "nichts" beziehen, was "kein Zugriffsmodifikator" bedeutet, dann hängt dies davon ab, obwohl eine sehr grobe Faustregel (sicherlich in C #) lautet, dass die Methode/Variable, wenn Sie keinen Zugriffsmodifikator explizit angeben Deklaration ist normalerweise so eingeschränkt , wie es sein kann. d.h.

public class MyClass
{
    string s = "";
}

ist effektiv das gleiche wie:

public class MyClass
{
    private string s = "";
}

Der verknüpfte MSDN-Artikel enthält eine vollständige Beschreibung, wenn kein expliziter Zugriffsmodifikator angegeben ist.

11
CraigTP

public - kann von jedermann überall zugegriffen werden.
privat - kann nur von der Klasse aus aufgerufen werden, zu der es gehört.
protected - kann nur von in der Klasse oder einem Objekt aus aufgerufen werden, das von der Klasse erbt.

Nichts ist wie null, aber in VB.
Statisch bedeutet, dass Sie eine Instanz dieses Objekts haben, eine Methode für jede Instanz dieser Klasse.

8
Tony

Noch ein visueller Ansatz des aktuellen Zugriffsmodifikator (C # 7.2). Hoffentlich hilft das Schema dabei, sich leichter daran zu erinnern
(Klicken Sie auf das Bild für eine interaktive Ansicht.)

interactive access modifiers svg

Draußen drinnen

Wenn Sie Probleme haben, sich an die zwei Wörter umfassenden Zugriffsmodifikatoren zu erinnern, denken Sie an außen-innen .

  • privat geschützt : privat außerhalb (dieselbe Assembly) protected inside (dieselbe Assembly)
  • geschützt intern : geschützt außerhalb (dieselbe Assembly) intern innerhalb (dieselbe Assembly)
6
user1810087

Der Status "Privat" gibt an, dass auf Variablen nur von Objekten derselben Klasse zugegriffen werden kann. Der geschützte Status erweitert diesen Zugriff auch auf Nachkommen der Klasse.

"Aus der obigen Tabelle können wir den Unterschied zwischen privat und geschützt ersehen. Ich denke, beide sind gleich. Also, was braucht man für zwei getrennte Befehle?"

Überprüfen Sie MSDN Link für weitere Informationen

4
Grant Hood

mmm ...

Statisch bedeutet, dass Sie auf diese Funktion zugreifen können, ohne eine Instanz der Klasse zu haben.

Sie können direkt aus der Klassendefinition zugreifen.

4
gbianchi

Achten Sie sorgfältig auf die Zugänglichkeit Ihres Unterrichts. Öffentliche und geschützte Klassen und Methoden sind standardmäßig für alle zugänglich.

Microsoft ist auch nicht sehr explizit darin, Zugriffsmodifikatoren (öffentliche, geschützte usw. Schlüsselwörter) anzuzeigen, wenn neue Klassen in Visual Studio erstellt werden. Seien Sie also vorsichtig und denken Sie über Ihre Zugänglichkeit für Ihre Klasse nach, da dies die Tür zu Ihren Implementierungsinternalen ist.

3
Patrick Peters

Diese Zugriffsmodifikatoren geben an, wo Ihre Mitglieder sichtbar sind. Sie sollten dies wahrscheinlich nachlesen. Nehmen Sie den von IainMH angegebenen Link als Ausgangspunkt.

Statische Member sind eins pro Klasse und nicht eins pro Instanz.

3
jpfollenius

Ich denke, es hängt mit gutem OOP Design zusammen. Wenn Sie Entwickler einer Bibliothek sind, möchten Sie das Innenleben Ihrer Bibliothek verbergen. Auf diese Weise können Sie später das Innenleben Ihrer Bibliothek ändern. Sie stellen also Ihre Member- und Helfer-Methoden als privat ein, und nur die Schnittstellenmethoden sind öffentlich. Zu überschreibende Methoden sollten geschützt werden.

2

C # hat insgesamt 6 Zugriffsmodifikatoren:

private : Das mit dieser Eingabehilfe deklarierte Element kann innerhalb des enthaltenden Typs sichtbar sein. Es ist für abgeleitete Typen, andere Typen in derselben Assembly oder nicht sichtbar Typen außerhalb der enthaltenden Assembly. der Zugriff ist nur auf den enthaltenden Typ beschränkt.

protected : Das mit dieser Eingabehilfe deklarierte Element kann in den Typen, die vom übergeordneten Typ in der übergeordneten Assembly abgeleitet sind, und in den Typen, die vom übergeordneten Typ abgeleitet sind, angezeigt werden außerhalb der enthaltenden Versammlung. der Zugriff ist auf abgeleitete Typen des enthaltenden Typs beschränkt.

internal : Das mit dieser Eingabehilfe deklarierte Mitglied kann in der Assembly angezeigt werden, die dieses Mitglied enthält. Es ist für keine Assembly außerhalb der enthaltenen Assembly sichtbar. d.h. der Zugriff ist darauf beschränkt, nur Assembly zu enthalten.

intern geschützt : Das mit dieser Eingabehilfe deklarierte Element kann innerhalb oder außerhalb der übergeordneten Assembly in den vom übergeordneten Typ abgeleiteten Typen angezeigt werden. Es ist auch sichtbar auf beliebige Typen innerhalb der enthaltenden Assembly. der Zugriff ist auf das Enthalten von Assembly oder abgeleiteten Typen beschränkt.

public : Das mit dieser Eingabehilfe deklarierte Mitglied kann in der Assembly angezeigt werden, die dieses Mitglied enthält, oder in jeder anderen Assembly, die auf die übergeordnete Assembly verweist. der Zugang ist nicht beschränkt.

C # 7.2 fügt eine neue Ebene der Barrierefreiheit hinzu:

private protected : Das mit dieser Eingabehilfe deklarierte Element kann in den Typen sichtbar sein, die von diesem enthaltenden Typ in der enthaltenden Assembly abgeleitet sind. Es ist nicht sichtbar für Typen, die nicht vom übergeordneten Typ abgeleitet sind oder außerhalb der übergeordneten Assembly liegen. der Zugriff ist auf abgeleitete Typen innerhalb der enthaltenden Baugruppe beschränkt.

Quelle einschließlich eines Beispielcodes des neuen Modifikators für den privaten geschützten Zugriff

1
Baccata