Entwickler-Ecke
C# - Die Sprache - Inkonsistenter Zugriff u. Zugriffsmodifzierer
_mk_ - Di 16.08.22 14:14
Titel: Inkonsistenter Zugriff u. Zugriffsmodifzierer
Hallo Zusammen.
Da ich nur über ein Paar C#-Grundlage verfüge, weiß ich (noch) nicht wie ich diese Compilerfehlermeldung
"Inkonsistenter Zugriff: Eigenschaftentyp "Countries" ist weniger zugreifbar als Eigenschaft "Person.Country"." beheben könnte. Die Enumeration möchte ich keineswegs öffentlich deklarieren. Ich habe leider keinen Ansatz, wie es lösen kann, noch habe ich keine Ahnung, wonach ich hier im Internet suchen sollte. Die Links zu CS0051 und CS0053 helfen mir leider nicht weiter.
Vielen Dank im Voraus.
Palladin007 - Di 16.08.22 14:20
Das geht nicht.
Du hast dem Enum keinen Zugriffsmodifizierer gegeben, damit greift der Default
internal.
Deine Person-Klasse ist aber
public, wodurch sie auch das Enum
public macht, ansonsten kann man die Person-Klasse nicht nutzen.
Das sagt der Fehler aus.
Lösen kannst Du das nur, indem Du das enum auch
public oder die betroffenen Inhalte der Person-Klasse
internal machst, doch dann kann man sie nicht mehr
public nutzen.
Aber was verstehst Du denn eigentlich unter
internal und
public?
Lies das mal nach, eventuell hast Du ja etwas falsch verstanden:
Access Modifiers [
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/access-modifiers]
Moderiert von
Th69: URl-Titel hinzugefügt
_mk_ - Di 16.08.22 14:38
Dann habe ich es in der Tat falsch verstanden. Unter den Modifizierer
public verstehe ich, dass die Klasse auch außerhalb des Assemblies instanziiert werden kann und unter
internal vertehe ich, dass auf die Klasse nur innerhalb des Assemblies zugegriffen werden kann. Wenn ich das Projekt kompliere, befinden sich doch alle Klassen und Stukturen in einem Assembly? Wo ist hier mein Denkfehler?
Vielen Dank im Voraus.
Th69 - Di 16.08.22 15:06
Wenn du eine Eigenschaft oder Methode als public deklarierst, so muß auch der Rückgabetyp public sein, sonst könnte der Aufrufer (aus einer anderen Assembly) ja gar nicht diesen Datentyp verwenden.
Edit: Die Schweiz schreibt sich im englischen auch leicht anders...
Palladin007 - Di 16.08.22 15:21
| Zitat: |
| Unter den Modifizierer public verstehe ich, dass die Klasse auch außerhalb des Assemblies instanziiert werden kann und unter internal vertehe ich, dass auf die Klasse nur innerhalb des Assemblies zugegriffen werden kann. |
Das ist korrekt.
| Zitat: |
| Wenn ich das Projekt kompliere, befinden sich doch alle Klassen und Stukturen in einem Assembly? Wo ist hier mein Denkfehler? |
Der Denkfehler ist, so meine Vermutung, dass es hier nicht um die Assembly geht, an der Du gerade arbeitest, sondern *andere* Assemblies, die deine Assembly nutzen wollen.
Das
public sagt aus, dass *andere* Assembly die Person-Klasse nutzen und den Konstruktor aufrufen können, das
internal verbietet das. Innerhalb deiner Assembly ist das egal, da kann man beides gleichermaßen nutzen.
Angenommen, deine Assembly liefert ein paar Tools für einen anderen Entwickler.
In dem Fall hast Du natürlich Klassen, Methoden, etc., die andere Entwickler nutzen wollen und das muss alles
public sein.
Allerdings hast Du auch Dinge, die nur für dich und deine Implementierung wichtig sind, die anderen Entwickler dürfen sie nicht nutzen, um nichts kaputt machen zu können. Das sollte in der Regel
internal sein.
Oder Du bist eine Firma, die Produkte verkauft und dafür Maschinen braucht.
Der Kunde ist nicht Teil der Firma, darf aber die Produkte kaufen und verwenden =>
public
Die Maschinen dürfen aber nur von Mitarbeitern der Firma verwendet werden =>
internal
Wenn es aber keine anderen Assemblies gibt, die dein Projekt nutzen sollen, dann ist das für dich ziemlich irrelevant.
Du kannst also getrost alles
public oder
internal machen, das ist dann eine Frage des Stils - solange die Regel, über die Du hier gestolpert bist, erfüllt wird.
Ich persönlich bevorzuge
internal.
_mk_ - Di 16.08.22 16:10
Th69 hat folgendes geschrieben : |
| Wenn du eine Eigenschaft oder Methode als public deklarierst, so muß auch der Rückgabetyp public sein, sonst könnte der Aufrufer (aus einer anderen Assembly) ja gar nicht diesen Datentyp verwenden. |
Langsam kommt Licht im Dunkeln. Ich war der Meinung, dass es völlig ausreichend ist, wenn in diesem Beispiel die Klasse
Person die Enumeration
Countries sieht und die Klasse weiß, woher er seine Informationen bekommt und diese bereitstellt. Deshalb wollte ich den standardmäßiger Zugriffsmodifzierer verwenden. Mir war nicht klar, dass quasie der gesamte Datentyp weitergereicht wird und deshalb der Aufrufer auch Kenntnis über den Datentyp benötigt. Vielleicht denke ich noch nicht objektorientiert genug.
Ich habe da noch ein ganz viel zu lernen.
Th69 hat folgendes geschrieben : |
| Edit: Die Schweiz schreibt sich im englischen auch leicht anders... |
Danke für den Hinweis. Wobei es sich eigentlich nur um kleines Beispiel handelte. Switzerland soll es natürlich heißen.
_mk_ - Mi 17.08.22 10:55
Palladin007 hat folgendes geschrieben : |
Angenommen, deine Assembly liefert ein paar Tools für einen anderen Entwickler.
In dem Fall hast Du natürlich Klassen, Methoden, etc., die andere Entwickler nutzen wollen und das muss alles public sein.
Allerdings hast Du auch Dinge, die nur für dich und deine Implementierung wichtig sind, die anderen Entwickler dürfen sie nicht nutzen, um nichts kaputt machen zu können. Das sollte in der Regel internal sein.
Oder Du bist eine Firma, die Produkte verkauft und dafür Maschinen braucht.
Der Kunde ist nicht Teil der Firma, darf aber die Produkte kaufen und verwenden => public
Die Maschinen dürfen aber nur von Mitarbeitern der Firma verwendet werden => internal
|
Vielen Dank für Deine Ausführung und für Dein Beispiel.
Ich tue mich aber noch etwas schwer damit. Aber ich denke, das sollte aber für den Anfang reichen.
Ralf Jansen - Mi 17.08.22 16:24
Vielleicht kurz aus einer anderen Richtung.
Es wäre ein Kompiler denkbar der deinen Code zuläßt aber was würde das aber bedeuten?
Der Konstruktor ist public. Könntest du dann im public Scope eine Person erzeugen? Nein denn ein new Person(Countries.Austria) geht nicht da du Countries nicht benutzen darfst es ist internal.
Bei der Property stellen wir uns vor du hättest von irgendwoher im public scope eine Instanz von Person an der Hand. Könntest du irgendwas mit der Property anfangen. Du könntest ein meineLiebePersonInstanz.Country; aufrufen. Wenn du den returnten enum ignorierst. Macht das Sinn? Nein. Könntest du irgendwas sinnvolles machen? Z.B. den Wert prüfen via if (meineLiebePersonInstanz.Country == Countries.Austria). Nö wieder das Problem das du Countries nicht benutzen darfst.
Ergo du könntest niemals den Person Typ außerhalb des internal scope benutzen selbst wenn dein Code zulässig wäre. Ergo ist der Error den der Compiler liefert eigentlich eher ein Service der dir sagt es ist sinnlos die Klasse public zu machen. Er meldet es halt nicht nur sondern erfordert es auch hart.
_mk_ - Do 18.08.22 14:24
Vielen Dank für Deine Erklärung,
Ralf Jansen. Es wird jetzt immer deutlicher, warum und wie ich die Zugriffsmodifierer einzusetzen habe. Leider wird dieses Thema in den Büchern, die ich zu C# lese, nur sehr kurz behandelt.
OOP ist noch sehr abstrakt für mich. Daran gewöhne ich mich erst langsam.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!