Es ist nichts Falsches daran, eine Schnittstelle zu haben, die eine andere Schnittstelle erbt, ohne neue Mitglieder hinzuzufügen, wenn erwartet wird, dass alle Implementierungen der letzteren Schnittstelle in der Lage sind, nützliche Dinge zu tun, die einige Implementierungen der ersteren möglicherweise nicht können. In der Tat ist es ein gutes Muster, das IMHO eher in Dingen wie dem .net Framework hätte verwenden sollen, zumal ein Implementierer, dessen Klasse natürlich die von der stärker abgeleiteten Schnittstelle implizierten Einschränkungen erfüllen würde, dies einfach durch Implementieren der stärker abgeleiteten Schnittstelle anzeigen kann , ohne den Implementierungscode oder die Deklarationen der Mitglieder ändern zu müssen.
Angenommen, ich habe die folgenden Schnittstellen:
Schnittstelle IMaybeMutableFoo {
Bar Thing {get; set;} // und auch andere Eigenschaften
bool IsMutable;
IImmutableFoo AsImmutable ();
}
Schnittstelle IImmutableFoo: IMaybeMutableFoo {};
Es wird IImmutableFoo.AsImmutable()
erwartet, dass eine Implementierung von sich selbst zurückgibt. Von einer Implementierung einer veränderlichen Klasse wird IMaybeMutableFoo.AsImmutable()
erwartet, dass sie ein neues, tief unveränderliches Objekt zurückgibt, das eine Momentaufnahme der Daten enthält. Eine Routine, die einen Schnappschuss der in einer gespeicherten Daten speichern möchte, kann zu IMaybeMutableFoo
Überlastungen führen:
public void StoreData (IImmutableFoo ThingToStore)
{
// Das Speichern der Referenz ist ausreichend, da bekannt ist, dass ThingToStore unveränderlich ist
}
public void StoreData (IMaybeMutableFoo ThingToStore)
{
StoreData (ThingToStore.AsImmutable ()); // Rufe die spezifischere Überladung auf
}
In Fällen, in denen der Compiler nicht weiß, dass es sich bei dem zu speichernden Objekt um einen handelt IImmutableFoo
, ruft er auf AsImmutable()
. Die Funktion sollte schnell zurückkehren, wenn das Element bereits unveränderlich ist, ein Funktionsaufruf über eine Schnittstelle jedoch noch einige Zeit in Anspruch nimmt. Wenn der Compiler weiß, dass das Element bereits ein Element ist IImmutableFoo
, kann er den unnötigen Funktionsaufruf überspringen.
IAnimal
undIDog
sind schreckliche Tautologienamen!