Zugriffsmodifikatoren in C#: public private protected internal
Stell dir vor, du schreibst in deiner Ausbildung oder im Studium eine Klasse `Bankkonto` mit dem Feld `kontostand`. Zwei Wochen später ruft ein Kollege an: „Warum kann ich den Kontostand einfach auf eine Million setzen?" Die Antwort: Dein Feld war `public`. Genau dafür gibt es Zugriffsmodifikatoren in C# - sie legen fest, wer auf Klassen, Methoden und Variablen zugreifen darf. Ob Azubi, Student oder Berufseinsteiger: Wer diese Sichtbarkeitsebenen verinnerlicht, schreibt automatisch saubereren...
Von Marcel Schmidtpeter 17. Aug. 2026
Stell dir vor, du schreibst in deiner Ausbildung oder im Studium eine Klasse `Bankkonto` mit dem Feld `kontostand`. Zwei Wochen später ruft ein Kollege an: „Warum kann ich den Kontostand einfach auf eine Million setzen?" Die Antwort: Dein Feld war `public`. Genau dafür gibt es Zugriffsmodifikatoren in C# - sie legen fest, wer auf Klassen, Methoden und Variablen zugreifen darf.
Ob Azubi, Student oder Berufseinsteiger: Wer diese Sichtbarkeitsebenen verinnerlicht, schreibt automatisch saubereren und sichereren Code.
Was sind Zugriffsmodifikatoren in C#?
Zugriffsmodifikatoren (englisch: access modifiers) sind Schlüsselwörter, die bestimmen, von wo aus im Code auf ein Element zugegriffen werden darf. C# kennt sechs davon - die vier wichtigsten sind `public`, `private`, `protected` und `internal`.
Stell dir eine Firma vor: Dein eigener Schreibtisch (`private`) gehört nur dir. Das Büro deiner Abteilung (`internal`) betreten nur Kollegen desselben Standorts. Der Besprechungsraum deiner Position (`protected`) ist für dich und deine Nachfolger in dieser Rolle zugänglich. Und die Empfangshalle (`public`) darf jeder betreten.
Merke: Zugriffsmodifikatoren sind der Werkzeugkasten der Datenkapselung - eines der vier Grundprinzipien der objektorientierten Programmierung (mehr dazu in OOP Prinzipien C#).
Welche Zugriffsmodifikatoren gibt es in C#?
Die folgende Tabelle zeigt dir, wer jeweils zugreifen darf:
Modifikator | Sichtbar für | Typischer Einsatz |
`private` | Nur die eigene Klasse | Felder, interne Hilfsmethoden |
`public` | Jeder, überall | Öffentliche Schnittstelle (Methoden, Properties) |
`protected` | Eigene Klasse + abgeleitete Klassen | Bei Vererbung |
`internal` | Alle Klassen derselben Assembly | Klassen innerhalb eines Projekts |
Zwei Kombinationen existieren zusätzlich: `protected internal` (abgeleitete Klassen ODER gleiche Assembly) und `private protected` (nur abgeleitete Klassen UND gleiche Assembly, erst ab C# 7.2). Die brauchst du selten - merke dir nur, dass es sie gibt.
Was bedeutet `private`?
`private` bedeutet: Nur Code innerhalb derselben Klasse darf auf das Element zugreifen. Nicht mal eine abgeleitete Klasse kommt heran.
public class Konto
{
private decimal kontostand; // nur innerhalb von Konto nutzbar
private void ProtokolliereZugriff()
{
Console.WriteLine("Zugriff um " + DateTime.Now);
}
}Merke: Wenn du bei einem Klassenmitglied gar nichts angibst, ist es automatisch `private`. Ausnahme: Mitglieder von Schnittstellen (`interface`) sind immer öffentlich - dort darfst du keinen Modifikator angeben.
Wann nutzt du `public`?
`public` macht ein Element von überall aus sichtbar - aus anderen Klassen, anderen Namespaces, sogar aus anderen Projekten. Nutze es für das, was deine Klasse bewusst der Welt anbietet: Methoden wie `Einzahlen()`, Properties wie `Kontostand`.
Aber Vorsicht: `public` ist kein Freibrief. Jede öffentliche Methode ist ein Vertrag mit allen Nutzern deiner Klasse. Änderst du später etwas daran, kann das überall im Programm Fehler auslösen.
Faustregel: So privat wie möglich, so öffentlich wie nötig.
Wann brauchst du `protected`?
`protected` erlaubt den Zugriff aus der eigenen Klasse und aus allen Klassen, die davon erben. Das brauchst du, sobald Vererbung ins Spiel kommt - ein Thema, das ich ausführlich in C# base virtual override erkläre.
public class Konto
{
protected string kontoinhaber; // Kindklassen duerfen zugreifen
}
public class Girokonto : Konto
{
public void ZeigeInhaber()
{
Console.WriteLine(kontoinhaber); // erlaubt, weil protected
}
}Von außen bleibt `kontoinhaber` trotzdem unsichtbar - `protected` öffnet die Tür nur für die Familie, nicht für Fremde.
Was bedeutet `internal`?
`internal` beschränkt den Zugriff auf die eigene Assembly - das ist eine kompilierte Einheit, zum Beispiel eine `.dll`- oder `.exe`-Datei. Alles, was `internal` ist, kannst du also innerhalb deines Projekts frei nutzen, aber nicht aus einem anderen Projekt heraus.
Praktisch: Auch hier gibt es einen Standard. Eine Klasse auf oberster Ebene ohne Modifikator ist automatisch `internal`. Das verhindert, dass interne Hilfsklassen unbeabsichtigt Teil der öffentlichen Schnittstelle einer Bibliothek werden.
Merke: `internal` heißt sichtbar im eigenen Projekt, unsichtbar nach außen - ideal für Hilfsklassen in Bibliotheken.
Die offizielle Referenz zu allen sechs Modifikatoren findest du bei Microsoft Learn.
Praxisbeispiel: Ein sauber gekapseltes Bankkonto
So setzt du alle vier Modifikatoren sinnvoll ein:
using System;
namespace BankDemo
{
// internal: nur innerhalb dieses Projekts nutzbar
internal class Bankkonto
{
// private: der Kern der Kapselung
private decimal kontostand;
// protected: abgeleitete Klassen wie Girokonto duerfen mitreden
protected string kontoinhaber;
// public: die Schnittstelle nach aussen
public Bankkonto(string inhaber, decimal startkapital)
{
kontoinhaber = inhaber;
kontostand = startkapital;
}
public decimal Kontostand
{
get { return kontostand; }
// bewusst kein setter! Niemand soll den Stand direkt aendern
}
public void Einzahlen(decimal betrag)
{
if (betrag <= 0)
{
throw new ArgumentException("Betrag muss positiv sein");
}
kontostand += betrag;
}
public bool Abheben(decimal betrag)
{
if (betrag > kontostand)
{
return false; // nicht genug Guthaben
}
kontostand -= betrag;
return true;
}
}
class Program
{
static void Main(string[] args)
{
Bankkonto konto = new Bankkonto("Alex", 500m);
konto.Einzahlen(100m);
// konto.kontostand = 1000000m; // Compiler-Fehler! private ist gesperrt
Console.WriteLine("Kontostand: " + konto.Kontostand); // 600
}
}
}Siehst du den Effekt? Der Kontostand kann nur über `Einzahlen()` und `Abheben()` verändert werden - inklusive aller Prüfungen. Die Geschäftslogik lässt sich nicht umgehen.
Häufige Fehler bei Zugriffsmodifikatoren
Fehler 1: Felder auf `public` setzen. Anfänger machen oft alles öffentlich, damit keine Compiler-Fehler entstehen. Falsch gedacht - so zerstörst du die Kapselung und verlierst die Kontrolle über deine Daten.
// Falsch: jeder darf direkt schreiben
public decimal kontostand;
// Richtig: private Feld + kontrollierter Zugriff
private decimal kontostand;
public decimal Kontostand { get { return kontostand; } }Fehler 2: `private` und `protected` bei Vererbung verwechseln. Wer in einer Kindklasse auf ein Feld der Elternklasse zugreifen will und einen Compiler-Fehler bekommt, hat vermutlich `private` statt `protected` verwendet. Faustregel: `private` sperrt auch Erben aus, `protected` lässt sie rein.
Fehler 3: `internal` in mehreren Projekten übersehen. Deine Klasse funktioniert im Hauptprojekt, aber im Unit-Test-Projekt kommt „Typ nicht erreichbar"? Dann ist sie `internal`, und das Testprojekt ist eine eigene Assembly. Abhilfe schafft das Attribut `InternalsVisibleTo`, mit dem du gezielt ein anderes Projekt zulassen kannst.
Übungstipp: Eigenen Code auditieren
Öffne ein eigenes (oder dein Ausbildungs-)Projekt und suche mit der IDE nach Feldern mit `public`. Frage bei jedem: Braucht das wirklich die ganze Welt? Baue dann ein öffentliches Feld in ein `private` Feld plus `public` Property um. Du wirst dabei sofort über Stellen stolpern, an denen Code ungeprüft auf Daten zugreift - der beste Lerneffekt.
FAQ: Häufige Fragen zu C# Zugriffsmodifikatoren
Was ist der Standard-Zugriffsmodifikator in C#?
Klassenmitglieder (Felder, Methoden, Properties) ohne Angabe sind automatisch `private`. Klassen auf oberster Ebene sind standardmäßig `internal`.
Wann nutze ich `protected` statt `private`?
Sobald abgeleitete Klassen auf das Element zugreifen sollen. Bei `private` sind auch Erben ausgesperrt.
Ist `protected internal` eine UND-Verknüpfung?
Nein. `protected internal` bedeutet `protected` ODER `internal` - also abgeleitete Klassen in beliebigen Assemblies plus alle Klassen der eigenen Assembly. Die UND-Variante ist `private protected`.
Warum nicht einfach alles `public` machen?
Weil du dann die Kapselung verlierst: Jeder Code kann jeden Zustand ändern, Prüfungen lassen sich umgehen, Fehler werden schwerer findbar. Restriktive Sichtbarkeit schützt deine Geschäftslogik.
Was ist eine Assembly in C#?
Eine kompilierte Code-Einheit, typischerweise eine `.dll`- oder `.exe`-Datei. `internal` grenzt die Sichtbarkeit genau auf diese Einheit ein.
Fazit
Die vier wichtigsten C# Zugriffsmodifikatoren - `public`, `private`, `protected` und `internal` - steuern, wer deinen Code sehen und benutzen darf. Denke an die Faustregel „so privat wie möglich, so öffentlich wie nötig" - und fange am besten bei deinem nächsten eigenen Projekt an, sie konsequent anzuwenden. Auch bei der Frage, ob du überhaupt vererben solltest, lohnt ein Blick auf C# Komposition vs. Vererbung.
Wenn dich Themen wie Kapselung oder Vererbung in deiner Ausbildung, im Studium oder im Berufseinstieg noch unsicher machen: Bei study-it.education findest du persönliche IT-Nachhilfe, die genau dort ansetzt, wo du gerade stehst. Schau vorbei und vereinbare dein erstes Gespräch.
Brauchst du jemand, der das mit dir durchgeht?
Statt nochmal lesen: 30 min mit einem Senior-Dev.
Kostenloses Erstgespräch buchen →
Stell dir vor, du schreibst in deiner Ausbildung oder im Studium eine Klasse `Bankkonto` mit dem Feld `kontostand`. Zwei Wochen später ruft ein Kollege an: „Warum kann ich den Kontostand einfach auf eine Million setzen?" Die Antwort: Dein Feld war `public`. Genau dafür gibt es Zugriffsmodifikatoren in C# - sie legen fest, wer auf Klassen, Methoden und Variablen zugreifen darf. Ob Azubi, Student oder Berufseinsteiger: Wer diese Sichtbarkeitsebenen verinnerlicht, schreibt automatisch saubereren...
marcel.schmidtpeter@study-it.education →Mehr Lesestoff
C# LINQ filtern und transformieren: Einfach erklärt mit Beispielen
LINQ macht Datenfilterung in C# kinderleicht: Mit Where, Select & Co. filterst und transformierst du Listen in wenigen Zeilen – hier lernst du wie!
C# Nullable einfach erklärt: So vermeidest du NullReferenceExceptions
Nullable-Typen in C# markieren Variablen, die null sein dürfen – und helfen dir, NullReferenceExceptions früh zu erkennen und zu vermeiden.
C# Lambda Expression einfach erklärt: Syntax & Beispiele
Lambda-Ausdrücke in C# verständlich erklärt: Syntax, Func & Action sowie praxisnahe Beispiele für Azubis, Studenten und Berufseinsteiger.