Czy metody rozszerzające można zastosować do interfejsów?

123

Czy można zastosować metodę rozszerzenia do interfejsu? (Pytanie w C #)

Ma to na przykład umożliwić osiągnięcie następujących celów:

  1. stworzyć interfejs ITopology

  2. utwórz metodę rozszerzenia dla tego interfejsu (np. public static int CountNodes (ta topologia ITopology, jeśli))

  3. wtedy podczas tworzenia klasy (np. MyGraph), która implementuje ITopology, miałaby automatycznie rozszerzenie Count Nodes.

W ten sposób klasy implementujące interfejs nie musiałyby mieć ustawionej nazwy klasy, aby była zgodna z tym, co zostało zdefiniowane w metodzie rozszerzenia.

Greg
źródło

Odpowiedzi:

189

Oczywiście, że mogą; większość Linq jest zbudowana wokół metod rozszerzania interfejsu.

Interfejsy były faktycznie jedną z sił napędowych rozwoju metod rozszerzeń; Ponieważ nie mogą zaimplementować żadnej ze swoich funkcji, metody rozszerzające są najłatwiejszym sposobem powiązania rzeczywistego kodu z definicjami interfejsów.

Zobacz klasę Enumerable dla całej kolekcji metod rozszerzających zbudowanych wokół IEnumerable<T>. Wdrożenie jednego jest takie samo, jak wdrożenie jednego dla klasy:

public static class TopologyExtensions
{
    public static void CountNodes(this ITopology topology)
    {
        // ...
    }
}

Nie ma nic szczególnego w metodach rozszerzających, jeśli chodzi o interfejsy; metoda rozszerzająca jest po prostu metodą statyczną, do której kompilator stosuje pewien cukier składniowy, aby wyglądała, jakby metoda była częścią typu docelowego.

Aaronaught
źródło
33
Odp: „Oczywiście” - myślę, że pytanie ujawnia zapach architektury, o którym wspominasz w sposób dorozumiany. Jeśli możesz mieć rozszerzenia na interfejsach, dlaczego interfejsy nie mogą zawierać zaimplementowanych metod? Zrozumiałe jest myślenie, że którekolwiek interfejsy powinny mieć konkretne metody, lub, gdy już wiesz, że nie mogą, myśleć, że metody rozszerzające nie powinny być dozwolone jako realna kludge. (Ale tak jest. Nie kłócą się z twoją doskonałą odpowiedzią, tylko „oczywiście” i link do IEnum, nie LINQ .; ^ D) Coś tam śmierdzi!
ruffin
Chciałbym dodać nowości do komentarza @ruffin, że teraz możesz dodać domyślne implementacje do metod interfejsu C #. Źródło: devblogs.microsoft.com/dotnet/…
Vinigas
@ruffin Uważam, że to najbardziej zagmatwana decyzja architektoniczna w C #. Czasami kończy się to bałaganem w strukturze pół-interfejsu w połowie klasy. Mimo to uważam, że może być przydatny, gdy podejdzie się go z punktu widzenia programowania funkcjonalnego i będzie używany do wprowadzania narzędzi do interfejsów, a nie do implementowania funkcjonalności.
Guney Ozsan