öffentliche vs. interne Methoden für eine interne Klasse

81
internal class Foo
{
  public void Fee()
  {
    Debug.WriteLine("Fee");
  }

  internal void Fi()
  {
    Debug.WriteLine("Fi");
  }
}

Ich denke, dass Fee () und Fi () gleichermaßen zugänglich sind, da die gesamte Klasse bereits intern ist. Übersehe ich etwas? Gibt es einen Grund, in einem solchen Fall öffentlich oder intern für die Methoden zu wählen?

ScottS
quelle
2
@EricLippert hat heute seine Meinung gebloggt. ericlippert.com/2014/09/15/internal-or-public/#more-2353
ScottS

Antworten:

97

Die internal class FooDeklaration überschreibt die Zugänglichkeit der public void Fee()Methode und macht sie effektiv intern.

In diesem Fall hat die Verwendung von intern oder öffentlich für die Methoden den gleichen Effekt. Der einzige Grund, warum ich in einem solchen Fall öffentliche Methoden gegenüber internen Methoden wählen würde, wäre die Erleichterung des Übergangs zu einer öffentlichen Klasse in einer zukünftigen Version, falls Sie dies wünschen.

Reed Copsey
quelle
36

Das einzige, was hier in der Antwort fehlt, ist, warum Sie das tun würden.

Einige Bibliotheken haben viele Klassen, die nicht für den Benutzer der Bibliothek gedacht sind, sondern die als öffentlich gekennzeichnete Schnittstellen erben müssen. Zum Beispiel habe ich eine Bibliothek mit einer Klasse, die die IComparer-Schnittstelle erbt, die jedoch nur intern verwendet wird, und ich möchte den öffentlichen Aspekt meiner Bibliothek nicht überladen. Wenn ich die implementierte Compare-Funktion als intern markiere, beschwert sich der Compiler, dass ich den IComparer der Schnittstelle nicht implementiere.

Wie implementiere ich die Schnittstelle erfolgreich und verhindere gleichzeitig, dass sie im öffentlichen Bereich meiner Bibliothek zugänglich ist? Markieren Sie die Klasse als intern, aber die implementierte Funktion als öffentlich.


quelle
30

Eigentlich - es gibt einen großen Unterschied, wenn Sie Reflexion verwenden; Insbesondere kann Silverlight sehr verärgert sein, wenn Sie versuchen, über Reflektion auf interne Methoden zuzugreifen, selbst wenn Sie Zugriff gehabt hätten. Ich habe Fälle gesehen, in denen ich eine Methode veröffentlichen musste, damit der Code unter Silverlight funktioniert, obwohl er unter normalem .NET funktioniert.

Möglicherweise finden Sie dasselbe mit teilweisem Vertrauen in reguläres .NET.

Marc Gravell
quelle
3
Dies sind die schmutzigen Details, an denen ich immer interessiert bin. Wenn jedoch jemand Reflexion verwendet, um auf versteckte Mitglieder in meinen Klassen zuzugreifen, mache ich mir keine Sorgen, wenn es für sie schwierig ist.
ScottS
1
@ScottS - manchmal denken Sie über Ihre eigenen Typen nach - dh wo Sie normalerweise Zugriff auf die interne Methode haben, aber plötzlich nicht mehr.
Marc Gravell
9

Es würde einen Unterschied machen, wenn Ihre interne Klasse eine Schnittstelle implementieren soll. Die Methode, die eine Implementierung einer Schnittstelle darstellt, müsste öffentlich sein.

user1343819
quelle
7

Sie haben Recht, sowohl Gebühr als auch Fi sind gleichermaßen zugänglich.

Aus der CSharp-Sprachspezifikation 3.0 unter 3.5.2:

Die Zugänglichkeitsdomäne eines verschachtelten Mitglieds M, das in einem Typ T innerhalb eines Programms P deklariert ist, ist wie folgt definiert (wobei zu beachten ist, dass M selbst möglicherweise ein Typ sein kann):

• Wenn die deklarierte Zugänglichkeit von M öffentlich ist, ist die Zugänglichkeitsdomäne von M die Zugänglichkeitsdomäne von T.

Selbst wenn die Gebühr als öffentlich deklariert wird, ist sie genauso zugänglich wie Foo (dh intern).

eglasius
quelle
3

Gemäß der msdn-Dokumentation ist Ihre Foo-Klasse außerhalb Ihrer Assembly nicht zugänglich, sodass es keinen Unterschied macht, die Methoden als intern oder öffentlich zu markieren. Es macht sogar keinen Unterschied, wenn Sie das Attribut InternalsVisibleTo verwenden

Jhonny D. Cano -Leftware-
quelle
1

Ich würde nur mit internen Methoden arbeiten, wenn eine Klasse intern ist. Falls Sie Ihre Meinung ändern und die Klasse veröffentlichen, können Sie einfach einen Text ersetzen und fertig.

gnikolaropoulos
quelle