2012-06-01 16 views
11

Ist es möglich, eine C# -Basisklasse nur innerhalb der Bibliotheksbaugruppe verfügbar zu machen, in die sie kompiliert wurde, während andere Unterklassen, die von ihr erben, öffentlich sind?C# private (versteckte) Basisklasse

Zum Beispiel:

using System.IO; 

class BaseOutput: Stream   // Hidden base class 
{ 
    protected BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

public class MyOutput: BaseOutput // Public subclass 
{ 
    public BaseOutput(Stream o): 
     base(o) 
    { ... } 

    public override int Write(int b) 
    { ... } 
} 

Hier würde Ich mag die BaseOutput Klasse an Kunden meiner Bibliothek zu sein, unzugänglich, aber erlauben die Unterklasse MyOutput vollständig öffentlich zu sein. Ich weiß, dass C# nicht zulässt, dass Basisklassen einen restriktiveren Zugriff als Unterklassen haben, aber gibt es einen anderen legalen Weg, denselben Effekt zu erzielen?

UPDATE

Meine Lösung für diese Bibliothek ist die Basisklasse public und abstract zu machen und es mit zu dokumentieren „diese Basis nicht-Klasse direkt verwenden“. Ich mache auch den Konstruktor der Basisklasse internal, die effektiv verhindert, dass externe Clients die Klasse verwenden oder erben.

(Es ist eine Schande, weil andere O-O Sprachen lassen Sie mich Basisklassen versteckt haben.)

+0

warum machen Sie nicht den Konstruktor von 'BaseOutput' intern, so dass kein externer Code davon erben kann? –

+0

@mikez: Ja, das habe ich gemacht, siehe Update oben. –

+0

öffentliche Klasse mit internem Konstruktor vielleicht eine bessere Option (Beispiel in meiner Antwort) –

Antwort

12

Leider nicht. Sie können eine öffentliche Klasse nicht von einer internen oder privaten Klasse ableiten.

Sie müssen entweder die Basisklasse angeben oder Sie müssen alle Methoden für alle ähnlichen Klassen deklarieren. Wenn Sie auf die Route gehen, auf der Sie alle Methoden erneut deklarieren, ist es wahrscheinlich hilfreich, eine Hilfsklasse zu erstellen, die die eigentliche Implementierung enthält. Es ist immer noch ein bisschen Standard.

+0

Schade. Java lässt mich dies tun. –

+1

Warum "leider"? – stakx

+4

Weil es mir manchmal ziemlich viel Kochgeschirr erspart hätte. Zum Beispiel bei der Implementierung der gleichen Schnittstelle in mehreren Klassen. – CodesInChaos

5

Betrachten Sie ein Muster wie eine Fassade. Dafür sind sie da. Ich glaube nicht, dass Sie mit der direkten Vererbung das erreichen können, was Sie benötigen.

+0

Ich möchte nicht viele Weiterleitungsmethoden erstellen müssen. Der Hauptpunkt hinter der versteckten Basisklasse ist es, viele (allgemeine) Methoden nicht zu replizieren. –

+1

In der Tat sollte man die Komposition sowieso über die Vererbung bevorzugen (http: //en.wikipedia.org/wiki/Composition_over_inheritance) – jeroenh

+0

@jeroenh - Das ist das genaue Gegenteil von meinem Punkt. Ich möchte, dass die Basisklasse * most * der Methoden und Variablen implementiert, und ich möchte, dass jede abgeleitete Unterklasse * so wenig wie möglich implementiert *. –

1

Je nachdem, was „viele gemeinsame Methoden“ tun Sie etwas davon mit internen Erweiterungsmethoden erreichen kann:

internal static class MyStreamExtensions 
{ 
    internal static int UsefulOne(this Stream stream) 
    { 
    return 42; 
    } 
} 

Ein anderer Ansatz ist Konstruktor interne zu machen unbeabsichtigte Ableitung von dieser Klasse zu verhindern:

Dies wird Code im Vergleich zu "nicht wirklich sichtbaren" Zwischenklasse in der Hierarchie verständlicher machen.

Verwandte Themen