2016-06-15 5 views
2

erben Betrachten Sie den folgenden Code ein:Schnittstelle Vererbung in C#: Eigenschaft nicht get-Accessor

public interface IFoo 
{ 
    int Bar { get; } 
} 

public interface IModifiableFoo : IFoo 
{ 
    int Bar { set; } 
} 

public class FooImpl : IModifiableFoo 
{ 
    public int Bar { get; set; } 
} 

static void Main() 
{ 
    IModifiableFoo f = new FooImpl(); 
    int bar = f.Bar; // Compiler error 
} 

Dies ist die Fehlermeldung:

Fehler CS0154: Die Eigenschaft oder Indexer ‚MyNamespace.IModifiableFoo. Bar‘kann in diesem Zusammenhang nicht verwendet werden, da es den get-Accessor

fehlt

Seit IModifiableFoo inherits IFoo, die 012.Accessor (d.h. get_Bar() Methode) sollte zugänglich sein. Was geht hier vor sich?

Hinweis: Dies unterscheidet sich von der Frage Adding setter to inherited read-only property in C# interface, da diese Frage Compilerfehler beim Aufrufen von Getter über beschreibbare Schnittstelle nicht adressiert.

+2

Sie bekommen haben sollte [a Compiler-Warnung] (https://msdn.microsoft.com/en-us/library/3s8070fc.aspx), wenn Sie das getan hat, es ist ein Hinweis darauf, was falsch läuft. Außerdem ist die Frage, mit der Sie verbunden sind, immer noch das gleiche Problem, sie haben den nächsten Schritt nicht gemacht, die Warnung zu ignorieren und zu versuchen, die Eigenschaft trotzdem zu verwenden. EDIT: Eigentlich, es genauer zu lesen, ist es nicht das gleiche Problem, weil sie 'Get verwenden; set; t' in der abgeleiteten Schnittstelle, aber Sie verwenden nur 'set;' –

+1

Vielleicht liegt es daran, dass Ihr zweiter Balken den ersten Schatten wirft? Was passiert, wenn Sie speziell auf IFoo umstellen? – Neolisk

+3

Visual Studio 2012 gibt mir die Warnung "'Test.IFodiableFoo.Bar' verbirgt das geerbte Mitglied 'Test.IFoo.Bar'. Verwenden Sie das neue Schlüsselwort, wenn das Verstecken beabsichtigt war." Das sieht sicher genauso aus wie in der Frage, die Sie verlinkt haben. –

Antwort

4

Der Grund ist, dass Ihre IModifiableFoo Eigenschaft die Eigenschaft versteckt, die es von IFoo vererbt wird, anstatt es zu überschreiben. Wenn Sie also Ihre get Funktionalität in Ihrer abgeleiteten Schnittstelle haben möchten, müssen Sie sie explizit hinzufügen.

Eigentlich sollten Sie Ihre Bar Eigenschaft in IModifiableFoo mit new Schlüsselwort markieren, um explizit zu zeigen, dass es etwas dahinter verbirgt, um beim Nachschlagen des Codes nicht verwirrt zu werden.

+0

sicher, danke für die Erinnerung) – Carmine

1

Getter und Setter sind keine einzelnen Mitglieder. Ein Setter in einer Schnittstelle wird also nicht zum Getter der Basisschnittstelle hinzugefügt. Stattdessen definieren Schnittstellen nur Mitglieder, und dieses Mitglied ist hier eine lesbare oder beschreibbare Eigenschaft.

Die vererbende Schnittstelle definiert eine Eigenschaft (ein Member) mit demselben Namen wie die Basisschnittstelle. So wird das Element der Basisschnittstelle ausgeblendet. So mit zwei Schnittstellen, haben Sie jetzt zwei Mitglieder, die Sie explizit implementieren könnte:

int IFoo.Bar { get; } 
int IModifiableFoo.Bar { set; } 

Beachten Sie, dass der Compiler Sie sollten eine Warnung zu diesem Verhalten und berät Sie die new Tastatur in der Vererbungs Schnittstelle zu verwenden, um dies zu markieren als vorsätzliche:

public interface IModifiableFoo : IFoo 
{ 
    new int Bar { get; set; } 
} 
-1

verwenden Sie keine Eigenschaften und Schnittstellenvererbung hier. Verwenden Sie reguläre Methoden und zwei separate Schnittstellen:

public interface IFooReader 
{ 
    int GetBar(); 
} 

public interface IFooWriter 
{ 
    void SetBar(int value); 
} 

public class FooImpl : IFooReader, IFooWriter 
{ 
    public int GetBar() { /* ... */ } 
    public void SetBar(int value) { /* ... */ } 
}