2013-04-17 10 views
5

Powiedzmy mam interfejs wiele wiele odrębnych klas wdrożenia:Obejście do bycia w stanie umieścić kod w interfejsach

public interface IHaveObjects 
{ 
    object firstObject(); 
} 

(Uwaga: Nie mogę zrobić to abstrakcyjna klasa podstawowa jako Twórcy implementacji IHaveObjects może Mam już klasę podstawową.)

Teraz chcę dodać nową metodę do interfejsu, aby jeden implementator interfejsu mógł mieć dla niego specjalne zachowanie. Idealnie byłoby zrobić coś takiego:

public interface IHaveObjects 
{ 
    object firstObject(); 
    object firstObjectOrFallback() 
    { 
     return firstObject(); 
    } 
} 

następnie udać się do tego jednego implementor interfejsu i nadać jej ręczne:

public class ObjectHaverPlus : IHaveObjects 
{ 
    public override object IHaveObjects.firstObjectOrFallback() 
    { 
     return firstObject() ?? getDefault(); 
    } 
} 

Jednak to jest zabronione w C#, aby zapewnić ciało metody w sposób interfejs i chciałbym uniknąć odwiedzania każdego pojedynczego implementatora w wersji IHaveObjects, aby pominąć definicję firstObjectOrFallback(). (Wyobraź sobie, że istnieją setki lub tysiące)

Czy można to zrobić bez dużej ilości wkleić?

+1

Dlaczego nie utworzyć drugiego interfejsu dla tego specjalnego przypadku? Nie możesz mieć wielu dziedziczeń klas, ale możesz wdrożyć wiele interfejsów. – Tim

Odpowiedz

2

Co powiecie na wprowadzenie drugiego interfejsu, który dziedziczy po IHaveObjects.

Następnie wystarczy zmienić te klasy, które wymagają nowego interfejsu z nową metodą.

ta wygląda następująco:

interface I1 
    { 
     void Method1(); 
    } 

    interface I2 : I1 
    { 
     void Method2(); 
    } 
+0

Och ... Podoba mi się ... nie myślałem nawet o dziedziczeniu w mojej odpowiedzi. Głupek mnie :) – Tim

+0

Tak, ale nie jest to możliwe w języku C#. Dałem mu alternatywny sposób. – Tomtom

+0

@Tomtom Myślę, że to jest to, co chcę zrobić. Oznacza to wykonanie kolejnego sprawdzenia, czy obiekt ma rozszerzony interfejs, ale powinno być w porządku.Dziękuję – Patashu

1

I może źle zrozumieć Twoje pytanie, ale dlaczego nie użyć drugiego interfejsu, coś jak:

public interface IHaveObjectsEnhanced 
{ 

    object FirstObjectOrFallback(); 
} 

Następnie można wdrożyć pierwszy i drugi interfejs:

public class ObjectHaverPlus : IHaveObjects, IHaveObjectsEnhanced 
{ 

    public object FirstObject() 
    { 

    } 

    public object FirstObjectOrFallback() 
    { 
     return FirstObject() ?? GetDefault(); 
    } 

} 
2

To jest problem z interfejsami - nie mają żadnej domyślnej implementacji, więc Zmiany w nich są przełamujące zmiany - tzn. kod musi zostać zmodyfikowany, aby działał z nową wersją interfejsu.

Ponieważ twoje wdrożenia zawierają już klasy podstawowe - nie możesz przekształcić ich w klasy abstrakcyjne, ani C# mieć wielu dziedziczenia klas.

Co możesz zrobić, to myśleć - czy to naprawdę jest metoda na interfejsie? Czy może być zaimplementowany jako interfejs extension method (nie próbował tego, ale przypuszczam, że będzie działał dobrze)?

Jeśli jest to metoda na interfejsie i powinna tam pozostać - możesz pomyśleć o podzieleniu tego interfejsu na dwie części, po drugie dziedzicząc od pierwszego (IHaveObjectsAndSupportDefault : IHaveObjects) i używać tego interfejsu, w którym wartość domyślna jest naprawdę potrzebna (jak niektóre inne odpowiedzi wskazują).

Powiązane problemy