Chciałbym usłyszeć, jaka jest motywacja stojąca za większością zamkniętych klas w środowisku .Net. Jaka jest korzyść z zapieczętowania klasy? Nie mogę pojąć, jak niedopuszczenie do dziedziczenia może być przydatne i najprawdopodobniej nie jest jedyną osobą walczącą z tymi klasami.
Dlaczego więc framework jest zaprojektowany w ten sposób i czy nie byłaby to nieodwracalna zmiana polegająca na rozpakowaniu wszystkiego? Musi być inny powód, ale po prostu bycie złym?
.net
performance
mmiika
źródło
źródło
Odpowiedzi:
Artykuł MSDN dotyczący tego tematu to Ograniczanie rozszerzalności przez klasy uszczelniające .
źródło
Klasy powinny być przeznaczone do dziedziczenia lub zakazywać tego. Projektowanie do dziedziczenia wiąże się z kosztami:
Punkt 17 Efektywnej Java zawiera więcej szczegółów na ten temat - niezależnie od tego, że została napisana w kontekście Javy, porada dotyczy również .NET.
Osobiście chciałbym, żeby klasy były domyślnie zapieczętowane w .NET.
źródło
Wygląda na to, że oficjalne wytyczne Microsoftu dotyczące uszczelniania ewoluowały od czasu zadania tego pytania ~ 9 lat temu i przeszły od filozofii opt-in (domyślnie pieczęć) do rezygnacji (domyślnie nie pieczętuj):
Rzeczywiście, jeśli przeszukasz bazę kodu ASP.Net Core , znajdziesz tylko około 30 wystąpień
sealed class
, z których większość to atrybuty i klasy testowe.Uważam, że ochrona niezmienności jest dobrym argumentem za uszczelnieniem.
źródło
Znalazłem to zdanie w dokumentacji msdn: „Klasy zapieczętowane są używane głównie do zapobiegania wyprowadzaniu. Ponieważ nigdy nie mogą być używane jako klasy bazowe, niektóre optymalizacje w czasie wykonywania mogą nieco przyspieszyć wywoływanie zapieczętowanych elementów klas.”
Nie wiem, czy wydajność jest jedyną zaletą zajęć zamkniętych i osobiście chciałbym poznać inne powody ...
źródło
Wydajność jest ważnym czynnikiem, na przykład klasa string w java jest ostateczna (<- zapieczętowana), a powodem tego jest tylko wydajność. Myślę, że kolejnym ważnym punktem jest uniknięcie kruchego problemu z klasą bazową opisanego szczegółowo tutaj: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes. aspx
Jeśli zapewnisz strukturę, jest to ważne dla starszych projektów z możliwością konserwacji i uaktualnienia struktury, aby uniknąć kruchego problemu z klasą bazową
źródło
String
klasa może nawet nie być możliwa do podklasy, nawet jeśli nie była ostateczna.Sealed służy do zapobiegania „problemowi z kruchą klasą podstawową”. Znalazłem dobry artykuł w MSDN, który to wyjaśnia.
źródło
Uszczelnienie pozwala uzyskać niewielki wzrost wydajności. Jest to mniej prawdziwe w świecie JIT i leniwej pesymizacji niż w świecie, powiedzmy C ++, ale ponieważ .NET nie jest tak dobry jak pesymizacja, jak kompilatory java, głównie z powodu różnych filozofii projektowania, nadal jest przydatny. Mówi kompilatorowi, że może bezpośrednio wywoływać dowolne metody wirtualne, zamiast wywoływać je pośrednio przez vtable.
Jest to również ważne, gdy chcesz mieć „zamknięty świat” na przykład przy porównywaniu równości. Zwykle kiedy już zdefiniuję metodę wirtualną, jestem prawie gotowy do zdefiniowania pojęcia porównania równości, które naprawdę realizuje tę ideę. Z drugiej strony mógłbym być w stanie zdefiniować to dla konkretnej podklasy klasy za pomocą metody wirtualnej. Zapieczętowanie tej klasy gwarantuje, że równość naprawdę obowiązuje.
źródło
Uszczelnienie klasy ułatwia zarządzanie zasobami jednorazowymi.
źródło
Aby określić, czy należy zapieczętować klasę, metodę lub właściwość, należy ogólnie wziąć pod uwagę następujące dwa punkty:
• Potencjalne korzyści, jakie może przynieść wyprowadzenie klas dzięki możliwości dostosowywania klasy.
• Potencjał, że klasy pochodne mogą zmodyfikować twoje klasy w taki sposób, że nie będą już działać poprawnie lub zgodnie z oczekiwaniami.
źródło
Kolejną kwestią jest to, że zapieczętowane klasy nie mogą zostać pominięte w testach jednostkowych. Z dokumentacji Microsoft :
źródło