2009-05-20 17 views
1

Sagen wir, ich erben eine Klasse, die mehrere öffentliche Eigenschaften und/oder Methoden hat, aber ich möchte nicht, dass sie öffentliche Eigenschaften/Methoden meiner Klasse sind - mit anderen Worten, ich möchte machen Diese Eigenschaften haben Eigenschaften meiner Klasse geschützt.Beschränken des Zugriffs auf vererbte Eigenschaften C#

Kann dies erreicht werden?

Ich hoffe, ich war klar genug, wenn nicht bitte lassen Sie es mich wissen, wird versuchen, mich besser zu erklären.

EDIT:

Richtig, ich danke Ihnen allen für die Antworten aber ich glaube nicht, dass ich klar genug war. Was ich versuche zu erreichen, ist dies:

Ich schrieb ein Windows-Steuerelement, das ListView-Steuerelement erweitert. ListView hat eine öffentliche Sammlung Elemente, die geändert werden können. Das ist alles in Ordnung, aber ich habe neue Methoden zum Hinzufügen von Elementen zu listview geschrieben, weil ich zusätzliche Daten benötige.

Es funktioniert alles gut, aber die Items-Sammlung kann immer noch durch irgendetwas modifiziert werden, was ein Problem ist, denn wenn ein Element durch direkte Manipulation der Items-Sammlung hinzugefügt wird, werden nicht alle Daten gesammelt Error.

Da wir hoffen, dieses Steuerelement mehrmals in verschiedenen Projekten wiederverwenden zu können, befürchten wir, dass früher oder später die Standardmethode zum Hinzufügen von Elementen zur Items-Auflistung verwendet wird (nur eine Frage der Zeit). Wir suchen nur nach einer Möglichkeit, dies zu verhindern, wie zum Beispiel eine Ausnahme auszulösen, wenn die Items-Sammlung größer wird, aber so, wie es beabsichtigt war.

Ich hoffe, das alles macht jetzt Sinn.

Antwort

4

Sag niemals nie. Das ist wahrscheinlich nicht die beste Idee, aber es scheint für mich zu funktionieren. Dadurch werden Elemente ausgeblendet, indem sie in der Unterklasse erneut implementiert und dann mithilfe von Attributen ausgeblendet werden. Ich fügte eine "CustomExposedItems" -Eigenschaft hinzu, so dass Sie sehen können, dass die vorhandenen Elemente in der zugrunde liegenden ListView weiterhin verfügbar sind.

public partial class CustomListView : ListView 
{ 
    public CustomListView() 
    { 
     InitializeComponent(); 
    } 

    public System.Windows.Forms.ListView.ListViewItemCollection CustomExposedItems 
    { 
     get 
     { 
      return base.Items; 
     } 

    } 

    [EditorBrowsable(EditorBrowsableState.Never)]  
    [Browsable(false)]  
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    [Obsolete("Use the new custom way of adding items xyz")] 
    public new System.Windows.Forms.ListView.ListViewItemCollection Items  
    { 
     get { throw new NotSupportedException(); }  
    } 

} 
+0

+1; Es ist immer noch möglich, über Casting auf die Original Items zuzugreifen. Aber ich denke, es ist das Beste, was Sie erhalten können, ohne ein UserControl zu verwenden, das den ListView enthält (was zu noch schlimmeren Problemen führt). – mmmmmmmm

1

Sie können dies nicht durch Vererbung tun. Das ist eigentlich, was Vererbung ist. Ein ist-eine Relation kann die Schnittstelle nicht reduzieren. Die abgeleitete Klasse muss eine vollständige Repräsentation der Basisklasse sein.

Verwandeln Sie Ihre Erbschaft in eine Referenz. Sie können die Implementierung Ihrer "Basisklasse" wiederverwenden, indem Sie sie aufrufen. (Komposition statt Vererbung.) Wenn Sie einen Polymorphismus benötigen, fügen Sie eine allgemeine Schnittstelle hinzu oder verschieben Sie den gemeinsamen Teil in eine separate abstrakte Basisklasse.

3

Nein, das geht nicht. Das Beste, was Sie tun können, ist das Erstellen einer Klasse und das Umschließen der Basisklasse, ohne davon abgeleitet zu werden - aber das bricht natürlich die Vererbung. (Ich nehme an, Sie können nicht die Basisklasse ändern. Wenn Sie können, sollten Sie das Design zu überdenken, weil es wie die neue Klasse sieht nicht aus der Basisklasse ableiten sollte.)

class BaseClass 
{ 
    public String IWantThis { get; set; } 
    public String IDoNotWantThis { get; set; } 
} 

class MyClass 
{ 
    private BaseClass baseClass = new BaseClass(); 

    public String IWantThis 
    { 
     get { return this.baseClass.IWantThis; } 
     set { this.baseClass.IWantThis = value; } 
    } 
} 
4

Vererbung ist alles über den Worten „Sie können Verwenden Sie diese abgeleitete Klasse auf dieselbe Weise wie die Basisklasse, und sie bietet ein spezielles Verhalten. "

Wenn Sie nicht können die abgeleitete Klasse auf die gleiche Weise wie die Basisklasse verwenden, dann sollten Sie keine Vererbung verwenden: Sie brechen Liskov's Substitutability Principle. Verwenden Sie in einem solchen Fall Komposition statt Vererbung. (Persönlich verwende ich nicht so viel Klasse-zu-Klasse-Vererbung, weit bevorzugen Zusammensetzung - Ich finde, es gibt relativ wenige Fälle, in denen die Spezialisierung Aspekt wirklich ohne Probleme funktioniert. Wenn es funktioniert funktioniert es ist toll, aber!)

+0

Das Problem mit WinForms Kontrollen und Zusammensetzung (Usercontrol ein Listview in diesem Fall enthält) ist, dass Sie so viel Material in Ihrem Usercontrol neu zu implementieren haben es wie ein Listview verhalten zu lassen. Es ist also sehr unpraktisch, Komposition hier zu verwenden. – mmmmmmmm

0

Ich benutze nicht AOP, vielleicht PostSharp, um die Eigenschaft, die Sie nicht verwenden möchten, um zu legen, und dann können Sie es in einer angemessenen Weise mit Ihrem Aspekt umgehen.

Verwandte Themen