2009-10-29 11 views
6

W jakich okolicznościach (scenariusze użycia) zdecydowałbyś się na napisanie rozszerzenia zamiast podklasy obiektu?ocena kosztów/korzyści zastosowania metod rozszerzających w C# => 3.0

< pełne ujawnienie: Nie jestem pracownikiem MS; Nie znam osobiście Mitsu Furota; Wiem, że autor wspomnianej tutaj biblioteki Componax o otwartym kodzie źródłowym, ale nie mam z nim żadnych kontaktów biznesowych; Nie tworzę ani nie planuję stworzyć żadnego produktu komercyjnego z wykorzystaniem rozszerzeń: w sumie: ten wpis pochodzi z czystej inteligencji i ciekawości związanej z moją próbą (ciągłego) uświadamiania sobie "najlepszych praktyk">

Znajduję ideę Metody rozszerzeń "fajne" i oczywiście możesz robić z nimi "dalekie" rzeczy, jak w wielu przykładach, które możesz znaleźć w blogach Mitsu Furota (MS) link text.

Osobisty przyjaciel napisał bibliotekę Componax o otwartym kodzie źródłowym link text i jest tam kilka niezwykłych udogodnień; ale on jest w pełni dowództwem swojej małej firmy z całkowitą kontrolą nad wytycznymi kodowymi, a każda linia kodu "przechodzi przez jego ręce".

Chociaż są to spekulacje z mojej strony: sądzę/przypuszczam, że inne problemy mogą pojawić się w sytuacji, w której średnie i duże zespoły programowe używają rozszerzeń.

Patrząc na wytycznych MS pod adresem link text, można znaleźć:

W ogóle, prawdopodobnie będzie wywoływanie metod przedłużania znacznie bardziej częściej niż wdrażaniu własnych. ... Ogólnie zaleca się, aby implementować metody rozszerzające oszczędnie i tylko wtedy, gdy jest to konieczne. Ilekroć jest możliwy, kod klienta, który musi rozszerzyć się na , istniejący typ powinien to zrobić przez , tworząc nowy typ pochodzący z istniejącego typu . Aby uzyskać więcej informacji, zobacz zobacz Dziedziczenie (C# Programowanie Przewodnik). ... Gdy kompilator napotyka wywołanie metody, najpierw szuka dopasowania w typach instancji tego typu: . Jeśli nie zostanie znaleziona żadna dopasowana , wyszuka ona wszystkie typy rozszerzeń zdefiniowane dla typu i powiąże z pierwszą znalezioną metodą rozszerzenia .

I w ms za link text:

rozszerzenie metod przedstawić żadnych konkretnych luk w zabezpieczeniach. Nie można ich używać do podszywania się pod istniejące metody , ponieważ wszystkie kolizje nazw są rozstrzygane na korzyść instancji lub metody statycznej zdefiniowanej jako przez sam typ. Metody rozszerzeń nie mają dostępu do żadnych prywatnych danych w rozszerzonej klasie .

Czynniki, które wydają się dla mnie oczywiste, że to:

  1. Zakładam, że nie byłoby napisać rozszerzenie chyba że spodziewane go stosować bardzo ogólnie i bardzo często.Z drugiej strony: czy nie możesz powiedzieć tego samego o subklasie?

  2. Wiedząc, że możemy je skompilować do osobnej biblioteki dll i dodać skompilowaną bibliotekę dll, a następnie odwołać się do niej, a następnie użyć rozszerzeń: "jest cool", ale czy to "wyrównuje" koszt związany z kompilatorem jako pierwszym konieczności sprawdzenia, czy metody instancji są zdefiniowane jak opisano powyżej. Lub koszt, w przypadku "zderzenia nazw", korzystania z metod wywoływania statycznego, aby upewnić się, że wywoływane jest rozszerzenie, a nie definicji instancji?

Jak częste korzystanie z rozszerzeń wpłynęłoby na wydajność pracy lub zużycie pamięci: Nie mam pojęcia.

Tak, doceniam twoje myśli lub wiedząc o tym, jak/kiedy robisz, lub czego nie robisz, użyj Rozszerzeń, w porównaniu do podklasy.

dzięki, Bill

+1

wiele innych pytań dotyczących tego samego tematu: http://stackoverflow.com/questions/487904/what-advantages-ofextext-methods-have-you-found – snicker

+1

"Jak często korzystano z rozszerzeń wpływa na wydajność pracy lub zużycie pamięci: nie mam pojęcia. " - w żaden sposób nie wpływa na żadną z nich. Wywołanie metody statycznej jest dokładnie takie samo jak wywołanie nie-wirtualnej, nieinterfejsowej metody instancji z taką samą liczbą argumentów (zliczanie niejawnego "tego" w tym ostatnim przypadku). –

Odpowiedz

10

Moje największe wykorzystanie dla nich jest rozszerzenie zamkniętych-off API 3rd party.

W większości przypadków, gdy twórca oprogramowania oferuje interfejs API w systemie Windows w tych dniach, coraz bardziej kręci się w kierunku .NET, jeśli chodzi o rozszerzalność. Lubię to robić, ponieważ wolę polegać na własnych metodach, które mogę modyfikować w przyszłości i służyć jako globalny punkt wejścia do ich API, w przypadku gdy go zmieniają.

Poprzednio, gdy musiałem to robić i nie mogłem odziedziczyć obiektu API, ponieważ zostało zapieczętowane lub coś w tym stylu, polegałem na Adapter pattern, aby tworzyć własne klasy, które zawijały swoje obiekty. Jest to funkcjonalne, ale raczej nieeleganckie rozwiązanie. Metody rozszerzeń dają piękny sposób dodawania większej funkcjonalności do czegoś, nad czym nie masz kontroli.

Dla wielu innych użytkowników największe znaczenie ma dla nich LINQ!

LINQ nie byłoby możliwe bez metod rozszerzenia podanych do IEnumerable.

Powodem, dla którego ludzie je uwielbiają jest to, że dzięki kod staje się bardziej czytelny.

Zauważyłem Innym ważnym wykorzystanie metod rozszerzenie (w tym ja) jest, aby kod był bardziej czytelny, i sprawiają, że wyglądają jakby kod coś zrobić należącą gdzie to ma. Pozbywa się też straszliwej "statycznej" klasy-boga-klasy, którą wielokrotnie widziałem. Co wygląda lepiej ... Util.DecimalToFraction(decimal value); lub value.ToFraction();? Jeśli jesteś taki jak ja, ten drugi.

Wreszcie są tacy, którzy uważają "metodę statyczną" za EVIL!

Wielu "dobrych programistów" powie ci, że powinieneś unikać metod statycznych, szczególnie tych, którzy używają obszernych testów jednostkowych. Metody statyczne są trudne do przetestowania w niektórych przypadkach, ale nie są złe, jeśli są używane prawidłowo. Podczas gdy metody rozszerzania są statyczne ... nie wyglądają ani nie działają w ten sposób. To pozwala ci uzyskać te statyczne metody z twoich klas i na obiekty, do których naprawdę powinny być dołączone.

Odnośnie wydajności ..

metody rozszerzeń nie różnią się od wywołania metody statyczne, przekazując obiekt zostanie przedłużone jako parametr ... bo to co kompilator zamienia ją. Wspaniałą rzeczą jest to, że twój kod wygląda na czysty, robi to, co chcesz, a kompilator obsługuje za ciebie brudną robotę.

+0

Dzięki, Snicker, za tę bardzo przemyślaną odpowiedź i link do innych wiadomości na SO w twoim komentarzu. Przeczytałem wiele z tych innych postów, ale wciąż czułem potrzebę zadawania własnego pytania "smaku". Jestem już "fanem" użycia metod statycznych, pól itp., A dla mnie kwestia czytelności, którą podnosisz, jest jedną z określonych motywacji do korzystania z metod rozszerzeń. Jeśli kiedykolwiek dojdziemy do Właściwości rozszerzenia, jestem na to gotowy :) najlepsze, Bill - BillW 0 sekund temu – BillW

1

W niektórych przypadkach nie można używać podklasy: na przykład łańcuch jest zapieczętowany. Możesz jednak nadal dodawać metody rozszerzeń.

2

Biorąc podejście sub-classing vs. metod rozszerzenie wymaga kilka rzeczy, aby mogło być prawdziwe

  1. typ musi być rozszerzalna (nie-uszczelnione)
  2. wszystkich miejscach typ jest tworzonych musi obsługiwać wzór fabryczny sortów lub inny kod po prostu stworzy typ bazowy.

Dodanie metody rozszerzenia nie wymaga naprawdę nic poza używaniem kompilatora C# 3.0+.

Ale co najważniejsze, hierarchia dziedziczenia powinna reprezentować relację is-a. Nie wydaje mi się, aby dodać 1 lub 2 nowe metody/zachowania do klasy naprawdę wyrażającej ten typ relacji. Zamiast tego zwiększa istniejące zachowanie. Klasa wrapper lub metoda rozszerzenia znacznie lepiej pasuje do scenariusza.

4

Używam metod rozszerzających jako sposobu na poprawić funkcjonalność klas bez zwiększania złożoności klasy. Możesz utrzymywać swoje zajęcia w prosty sposób, a następnie dodać swoją powtarzalną pracę później jako rozszerzenie.

Metody rozszerzeń Min() i Max() są świetnymi tego przykładami. Równie łatwo można zadeklarować prywatną metodę, która by je obliczyła, ale metoda rozszerzenia zapewnia lepszą czytelność, sprawia, że ​​funkcjonalność jest dostępna dla całego projektu i nie wymagała tworzenia tablicy złożonych obiektów.

Powiązane problemy