C# Zugriffsmodifikatoren verstehen
In diesem Artikel werden wir uns mit C#-Zugriffsmodifikatoren beschäftigen, die die Sichtbarkeit und Zugänglichkeit von Typen, Methoden und Variablen in C# definieren. Tim Corey erklärt in seinem Video "C# Access Modifiers (beyond public and private) - what they are, how to use them, and best practices" verschiedene Access Modifiers und demonstriert deren praktische Anwendung in einer Konsolenanwendung.
In diesem Artikel wird erklärt, was Tim abgedeckt hat, zusammen mit Codebeispielen, um Ihr Verständnis zu verbessern. Die Zeitstempel ermöglichen es Ihnen, dem Video zu folgen, um eine praxisnahe Erfahrung zu machen.
Was sind Zugriffsmodifikatoren?
Einführung
Tim Corey beginnt mit einer Einführung in die Zugriffsmodifikatoren und erklärt, dass diese in C# bestimmen, wer eine Ressource sehen und nutzen kann. Während wir mit den allgemein verwendeten öffentlichen und privaten Modifikatoren vertraut sind, erforscht Tim sechs verschiedene Zugriffsmodifikatoren und ihre Anwendungsfälle.
Demo-Anwendung erklärt
Tim richtet eine einfache Anwendung ein, um zu demonstrieren, wie verschiedene Zugriffsmodifikatoren funktionieren. Die Anwendung besteht aus einer Konsolen-Benutzeroberfläche und einer Demo-Bibliothek, beide im .NET Framework.
Projektstruktur:
- Konsole UI: Eine Konsolenanwendung zum Testen von Zugriffsmodifikatoren.
- Demo-Bibliothek: Eine Klassenbibliothek, in der verschiedene Zugriffsmodifikatoren demonstriert werden.
public class AccessDemo
{
private void PrivateDemo() { }
internal void InternalDemo() { }
public void PublicDemo() { }
}
public class AccessDemo
{
private void PrivateDemo() { }
internal void InternalDemo() { }
public void PublicDemo() { }
}
1. Privat
Was es ist:
Der private Modifikator schränkt den Zugriff auf die Methode, das Feld oder die Eigenschaft nur innerhalb der Klasse ein, in der sie definiert ist.
Codebeispiel:
public class AccessDemo
{
private void PrivateDemo()
{
Console.WriteLine("Private method can only be accessed within this class.");
}
public void CallPrivateDemo()
{
PrivateDemo(); // Works because it's within the same class
}
}
public class AccessDemo
{
private void PrivateDemo()
{
Console.WriteLine("Private method can only be accessed within this class.");
}
public void CallPrivateDemo()
{
PrivateDemo(); // Works because it's within the same class
}
}
Erklärung: Die Methode PrivateDemo ist nur innerhalb der Klasse AccessDemo zugänglich. Im Video demonstriert Tim, dass von außerhalb der Klasse nicht darauf zugegriffen werden kann, selbst wenn sich andere Klassen im selben Projekt befinden.
Beste Praxis: Verwenden Sie private, wenn Sie den Zugriff auf die interne Funktionsweise Ihrer Klasse einschränken wollen, um sicherzustellen, dass sie nicht direkt von anderen Teilen Ihrer Anwendung aus geändert werden kann.
2. intern
Was es ist:
Der interne Modifikator ermöglicht den Zugriff auf die Methode oder Eigenschaft nur innerhalb derselben Assembly (des Projekts). Dies ist umfassender als der private Zugriffsmodifikator, da er alle Klassen innerhalb desselben Projekts einschließt.
Codebeispiel:
public class AccessDemo
{
internal void InternalDemo()
{
Console.WriteLine("Internal method is accessible within the same assembly.");
}
}
public class AccessDemo
{
internal void InternalDemo()
{
Console.WriteLine("Internal method is accessible within the same assembly.");
}
}
Erklärung: Die Methode InternalDemo kann von jeder Klasse innerhalb derselben Assembly, aber nicht von anderen Assemblys aus aufgerufen werden. Im Video zeigt Tim, dass intern den Zugriff innerhalb des gleichen Projekts erlaubt, aber den Zugriff von außen verweigert.
Best Practice: Verwenden Sie "intern" für Methoden oder Eigenschaften, die nur innerhalb der aktuellen Assembly verwendet werden sollen, z. B. Hilfsfunktionen oder Dienstprogramme, die nicht für externe Projekte zugänglich sein sollten.
3. öffentlich
Was es ist:
Der Modifikator public ermöglicht den Zugriff auf die Methode oder Eigenschaft von jeder anderen Klasse oder Assembly aus. Dies ist die freizügigste Zugriffsstufe.
Codebeispiel:
public class AccessDemo
{
public void PublicDemo()
{
Console.WriteLine("Public method can be accessed from any class.");
}
}
public class AccessDemo
{
public void PublicDemo()
{
Console.WriteLine("Public method can be accessed from any class.");
}
}
Erklärung: Die Methode PublicDemo ist von überall aus zugänglich, einschließlich anderer Klassen in derselben Assembly oder in anderen Assemblys. Tim zeigt, dass public der am häufigsten verwendete Zugriffsmodifikator ist, insbesondere bei der Freigabe von Methoden in Bibliotheken.
Best Practice: Verwenden Sie public für Methoden und Eigenschaften, auf die andere Teile der Anwendung oder externe Projekte zugreifen müssen, wie API-Endpunkte oder weit verbreitete Dienstprogramme.
4. Geschützt
Was es ist:
Der Protected Modifier erlaubt den Zugriff auf die Methode oder Eigenschaft innerhalb der Klasse, in der sie definiert ist, und in allen abgeleiteten Klassen (Vererbung). Dieser Modifikator ist nützlich für die objektorientierte Programmierung, insbesondere im Falle der Vererbung.
Codebeispiel:
public class AccessDemo
{
protected void ProtectedDemo()
{
Console.WriteLine("Protected method can be accessed within the class and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedDemo()
{
ProtectedDemo(); // Accessible because of inheritance
}
}
public class AccessDemo
{
protected void ProtectedDemo()
{
Console.WriteLine("Protected method can be accessed within the class and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedDemo()
{
ProtectedDemo(); // Accessible because of inheritance
}
}
Erklärung: Die Methode ProtectedDemo kann von der Klasse AccessDemo und von jeder Klasse, die von ihr erbt, aufgerufen werden. Tim erklärt, dass "protected" bei der Arbeit mit Vererbung weniger verbreitet, aber sehr nützlich ist.
Best Practice: Verwenden Sie protected, wenn Sie abgeleiteten Klassen den Zugriff auf bestimmte Methoden oder Eigenschaften erlauben wollen, diese aber nicht außerhalb der Klassenhierarchie zugänglich sein sollen.
5. Privat Geschützt
Was es ist:
Der private protected-Modifikator kombiniert die Regeln von private und protected. Sie schränkt den Zugriff auf Methoden oder Eigenschaften innerhalb der definierenden Klasse und abgeleiteter Klassen innerhalb derselben Assembly ein. Das bedeutet, dass sie ein höheres Schutzniveau und engere Grenzen für die vererbungsbasierte Zugriffskontrolle bietet als die geschützte.
Codebeispiel:
public class AccessDemo
{
private protected void PrivateProtectedDemo()
{
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallPrivateProtectedDemo()
{
PrivateProtectedDemo(); // Accessible because of inheritance within the same assembly
}
}
public class UnrelatedClass
{
public void TestAccess()
{
// PrivateProtectedDemo(); // Error: Not accessible in unrelated classes
}
}
public class AccessDemo
{
private protected void PrivateProtectedDemo()
{
Console.WriteLine("Private Protected method can be accessed within the same assembly and derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallPrivateProtectedDemo()
{
PrivateProtectedDemo(); // Accessible because of inheritance within the same assembly
}
}
public class UnrelatedClass
{
public void TestAccess()
{
// PrivateProtectedDemo(); // Error: Not accessible in unrelated classes
}
}
Erklärung: Die Methode PrivateProtectedDemo ist in der Klasse DerivedClass zugänglich, da sie von AccessDemo erbt und in derselben Assembly existiert. Sie kann jedoch in UnrelatedClass nicht aufgerufen werden, da diese Klasse nicht von AccessDemo erbt.
Best Practice: Verwenden Sie den privaten geschützten Zugriffsmodifikator sparsam, wenn Sie den Vererbungszugriff innerhalb derselben Assembly streng kontrollieren müssen. Dies ist besonders in Szenarien nützlich, in denen die Offenlegung von Methoden oder Eigenschaften über Baugruppen hinweg die Kapselung gefährden könnte.
6. geschütztes Internes
Was es ist:
Der geschützte interne Modifikator kombiniert die geschützte und die interne Zugriffsmodifizierungsebene. Sie ermöglicht den Zugriff aus derselben Assembly oder aus abgeleiteten Klassen, auch wenn diese in einer anderen Assembly liegen.
Codebeispiel:
public class AccessDemo
{
protected internal void ProtectedInternalDemo()
{
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedInternalDemo()
{
ProtectedInternalDemo(); // Accessible due to inheritance
}
}
public class AccessDemo
{
protected internal void ProtectedInternalDemo()
{
Console.WriteLine("Protected Internal method can be accessed within the same assembly or from derived classes.");
}
}
public class DerivedClass : AccessDemo
{
public void CallProtectedInternalDemo()
{
ProtectedInternalDemo(); // Accessible due to inheritance
}
}
Erklärung: Die Methode ProtectedInternalDemo ist innerhalb derselben Assembly und auch von jeder abgeleiteten Klasse, unabhängig von der Assembly, aus zugänglich.
Best Practice: Verwenden Sie protected internal, wenn Sie eine Methode sowohl für abgeleitete Klassen (in anderen Assemblies) als auch für Klassen in derselben Assemblies freigeben wollen, aber nicht für alle.
Warum nicht alles öffentlich machen?
Tim Corey erklärt, wie wichtig die Verwendung von Zugriffsmodifikatoren ist und warum nicht alles nur öffentlich sein sollte. Alles öffentlich zu machen, mag zwar bequem erscheinen, birgt aber auch erhebliche Risiken wie Datenschutzverletzungen, Bugs und Verwirrung bei der Entwicklung. Zugriffsmodifikatoren dienen dazu, Informationen zu sichern, unbeabsichtigten öffentlichen Zugriff zu verhindern und für Klarheit in Codebases zu sorgen.
1. Schutz von privaten Informationen
Tim erläutert, warum sensible Informationen wie Sozialversicherungsnummern (SSN) oder Kreditkartennummern nicht veröffentlicht werden sollten. Er demonstriert ein Beispiel für eine "schlechte Klasse", bei der Daten aufgrund eines öffentlichen Zugriffs offengelegt werden:
Schlechtes Beispiel:
public class User
{
public string SSN; // Anyone can access and modify it directly
}
public class User
{
public string SSN; // Anyone can access and modify it directly
}
Gutes Beispiel:
public class User
{
private string ssn;
public string GetMaskedSSN()
{
return "XXX-XX-" + ssn.Substring(ssn.Length - 4);
}
public void SetSSN(string value)
{
// Add validation if needed
ssn = value;
}
}
public class User
{
private string ssn;
public string GetMaskedSSN()
{
return "XXX-XX-" + ssn.Substring(ssn.Length - 4);
}
public void SetSSN(string value)
{
// Add validation if needed
ssn = value;
}
}
2. die Absicherung privater Methoden
Beginn: 35:11\
Tim erklärt, dass private Methoden helfen, Verhaltensweisen zu kapseln, die nicht direkt zugänglich sein sollten. Er verwendet das Beispiel einer DeleteUser-Methode als Teil eines größeren Prozesses wie der Abmeldung eines Mitarbeiters.
Schlechtes Beispiel:
public class UserManager
{
public void DeleteUser(int userId)
{
// Deletes the user without considering related processes
}
}
public class UserManager
{
public void DeleteUser(int userId)
{
// Deletes the user without considering related processes
}
}
Gutes Beispiel:
public class UserManager
{
public void OffboardUser(int userId)
{
RevokeAccess(userId);
DeleteUser(userId); // Used privately as part of offboarding
}
private void DeleteUser(int userId)
{
// Internal logic to delete the user
}
private void RevokeAccess(int userId)
{
// Logic to revoke system access
}
}
public class UserManager
{
public void OffboardUser(int userId)
{
RevokeAccess(userId);
DeleteUser(userId); // Used privately as part of offboarding
}
private void DeleteUser(int userId)
{
// Internal logic to delete the user
}
private void RevokeAccess(int userId)
{
// Logic to revoke system access
}
}
3. die Vermeidung von Fehlern
Zugriffsmodifikatoren verhindern Fehler, indem sie sicherstellen, dass Daten mit der richtigen Validierung gesetzt oder abgerufen werden. Tim veranschaulicht dies mit einem Beispiel unter Verwendung einer Age-Eigenschaft.
Schlechtes Beispiel:
public class Person
{
public int Age; // Can be directly set to an invalid value
}
public class Person
{
public int Age; // Can be directly set to an invalid value
}
Gutes Beispiel:
public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value < 0 || value > 120)
throw new ArgumentOutOfRangeException("Age must be between 0 and 120.");
age = value;
}
}
}
public class Person
{
private int age;
public int Age
{
get { return age; }
set
{
if (value < 0 || value > 120)
throw new ArgumentOutOfRangeException("Age must be between 0 and 120.");
age = value;
}
}
}
4. die Verwirrung verringern und die Klarheit verbessern
Die korrekte Verwendung von Zugriffsmodifikatoren vereinfacht die Entwicklung, indem nur das Notwendige offengelegt wird und Verwirrung vermieden wird. Wenn beispielsweise in einer Anwendung mit Tausenden von Methoden nur die öffentlichen Methoden offengelegt werden, wird sichergestellt, dass die Entwickler nur die relevanten Optionen sehen.
Beispiel:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}
5. Vorteile in größeren Anwendungen oder Bibliotheken
Für große Projekte erklärt Tim, wie die richtige Verwendung von Zugriffsmodifikatoren sicherstellt, dass nur die erforderlichen Teile einer Bibliothek offengelegt werden, wodurch die kognitive Belastung für Entwickler, die die Bibliothek verwenden, reduziert wird.
Beispiel:
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}
public class MathLibrary
{
public int Add(int a, int b) => a + b;
public int Subtract(int a, int b) => a - b;
private void LogCalculation(string operation, int result)
{
// Logging is internal and not exposed
}
}
Durch die korrekte Verwendung dieser Zugriffsmodifikatoren erleichtern Sie Ihre Arbeit und die Arbeit der anderen.
Abschluss
Tim Corey bietet einen klaren und praktischen Leitfaden zur Beherrschung von C#-Zugriffsmodifikatoren und zeigt, wie man sie effektiv einsetzt, um sichere, wartbare und professionelle Anwendungen zu erstellen. Seine detaillierten Erklärungen und Beispiele aus der Praxis machen dieses Thema für Entwickler aller Stufen zugänglich.
Um weitere Einblicke zu erhalten und diese Konzepte in Aktion zu sehen, sollten Sie sich Tims vollständiges Video ansehen und seinen Channel für wertvolle Inhalte zu C# und anderen Programmierthemen erkunden. Ein Muss für jeden, der seine Entwicklungsfähigkeiten verbessern möchte!
