So erstellen Sie einen Konstruktor, der nur von einer bestimmten Klasse verwendet werden kann. (C ++ Freund entspricht in c #)

8

Soweit ich weiß, gibt es in C # keine Unterstützung für das Schlüsselwort "friend" wie in C ++. Gibt es eine alternative Möglichkeit, eine Klasse zu entwerfen, die das gleiche Endergebnis erreichen kann, ohne auf das nicht verfügbare "Freund" -Schlüsselwort zurückzugreifen?

Für diejenigen, die es noch nicht wissen, erlaubt das Friend-Schlüsselwort dem Programmierer anzugeben, dass auf ein Mitglied der Klasse "X" nur von der Klasse "Y" zugegriffen werden kann. Aber zu jeder anderen Klasse erscheint das Mitglied privat, so dass sie nicht zugänglich sind. Die Klasse "Y" muss nicht von der Klasse "X" erben.

    
7wp 06.01.2010, 22:20
quelle

10 Antworten

8

Nein, es gibt keine Möglichkeit, das in C # zu tun.

Eine häufige Problemumgehung besteht darin, das Objekt zu erstellen, für das Sie den Konstruktor auf einer Schnittstelle verbergen möchten. Sie können dann das andere Objekt verwenden, um eine private, geschachtelte Klasse zu erstellen, die diese Schnittstelle implementiert, und sie über eine Factory zurückgeben. Dies verhindert, dass die Außenwelt Ihr Objekt direkt konstruiert, da sie die Schnittstelle immer sehen und mit ihr interagieren.

%Vor%     
Reed Copsey 06.01.2010, 22:23
quelle
2

Wie wäre es, wenn Sie explicity haben, um eine Schnittstelle zu implementieren, die nur für eine bestimmte Klasse sichtbar ist?

Etwas wie:

%Vor%

und stellen Sie dann sicher, dass IFriendOfX für Klasse X sichtbar ist. In Ihrer X-Klasse würden Sie die Methode aufrufen, indem Sie zuerst X an IFriendOfX übergeben und dann Foo () aufrufen. Ein weiterer Vorteil ist, dass es ziemlich selbstdokumentierend ist ... das heißt, es ist ziemlich nahe daran, das Friend-Schlüsselwort selbst zu haben.

    
Rodrick Chapman 06.01.2010 22:29
quelle
1

Nein. Der nächste, den Sie haben, ist ein internal -Konstruktor oder ein private -Konstruktor und eine separate Factory-Methode (wahrscheinlich internal , also haben Sie nicht viel gespeichert).

    
Marc Gravell 06.01.2010 22:23
quelle
1

Soweit ich weiß, ist das Schlüsselwort Internal in .NET am nächsten. Diese Frage wird mehr Licht ins Innere werfen: Intern in C #

    
John Kraft 06.01.2010 22:24
quelle
1

Das einzige, was mir dabei einfällt, wäre protected internal , aber das beschränkt sich nicht auf eine bestimmte Klasse. Der einzige Freundeskreis, den ich in c # kenne, ist eine Freundschaftsversammlung. Beschränkt sich nicht auf eine bestimmte Klasse.

Das Einzige, woran ich denken könnte, wäre, etwas wie das Folgende zu tun:

%Vor%

Der einzige andere Weg, an den ich denken könnte, wäre, eine Art Konstruktoreinspritzung zu machen, indem ich Reflektionen verwende, die innerhalb der Klasse deiner Freunde gemacht werden. Der Injektionsmechanismus würde es Ihnen erlauben, ihn auf das zu beschränken, was Sie wollen, könnte aber sehr mühsam sein. Werfen Sie einen Blick auf etwas wie Spring.Net für einige Injektionsfähigkeiten.

    
Joshua Cauble 06.01.2010 22:34
quelle
1

Was ist mit dem Erstellen einer privaten Klasse? Das tut genau das, was Sie zu beschreiben scheinen. Auf ein Mitglied der Klasse X kann nur von der Klasse Y zugegriffen werden, und auf jede andere Klasse wird es als privat betrachtet, da privat ist:

%Vor%     
Robert Rossney 06.01.2010 22:45
quelle
1

Als Workaround könnten Sie in Ihrem Konstruktor eine Bedingung erstellen, die Reflektion verwendet.

Zum Beispiel, wenn der Konstruktor von Class1 von Class2 aufgerufen werden muss:

%Vor%

BEARBEITEN:

Bitte beachten Sie, dass ich das nie in "echtem" Code machen würde. Technisch funktioniert es, aber es ist ziemlich eklig. Ich dachte nur, dass es kreativ war. :)

    
Andy West 06.01.2010 22:30
quelle
1

So habe ich es gelöst. Ich bin mir nicht sicher, ob es der "richtige" Weg ist, es zu tun, aber es erfordert minimalen Aufwand:

%Vor%     
hypehuman 21.11.2012 18:46
quelle
0

Sie können mit Reflection auf private Member / Methoden zugreifen.

Da es das Design-Tag hat, habe ich das Friend-Keyword nicht sonderlich gemocht. Es durchdringt die Verkapselung und das fühlte sich immer schmutzig für mich an.

    
48klocs 06.01.2010 22:30
quelle
0

Das hat ein bisschen gerochen. Es gibt noch viele andere Möglichkeiten, die Implementierung in C # zu verstecken. Die Beschränkung der Konstruktion auf bestimmte Klassen erreicht nicht viel.

Könnten Sie bitte mehr Informationen zum Zweck dieser Anforderung geben? Wie bereits beantwortet, ist internal die beste Übereinstimmung für die Einschränkung der Zugänglichkeit für die Klasse. Je nach Zweck gibt es Möglichkeiten, darauf aufzubauen.

    
Igor Zevaka 06.01.2010 22:31
quelle

Tags und Links