Współpracownik i ja przyglądaliśmy się zachowaniu new
słowa kluczowego w języku C #, ponieważ odnosi się ono do koncepcji ukrywania. Z dokumentacji :
Użyj nowego modyfikatora, aby jawnie ukryć element członkowski odziedziczony z klasy podstawowej. Aby ukryć dziedziczony element członkowski, zadeklaruj go w klasie pochodnej, używając tej samej nazwy, i zmodyfikuj go za pomocą nowego modyfikatora.
Przeczytaliśmy dokumentację i rozumiemy, co ona właściwie robi i jak to robi. Tym, na co tak naprawdę nie mogliśmy sobie poradzić, jest powód, dla którego musisz to zrobić. Modyfikator istnieje od 2003 roku i oboje pracujemy z .Net dłużej niż to i nigdy się nie pojawi.
Kiedy takie zachowanie byłoby konieczne w sensie praktycznym (np. W odniesieniu do uzasadnienia biznesowego)? Czy jest to funkcja, która przeżyła swoją przydatność, czy też to, co robi po prostu dość rzadko w tym, co robimy (w szczególności robimy formularze internetowe i aplikacje MVC oraz niektóre małe czynniki WinForms i WPF)? Próbując tego słowa kluczowego i bawiąc się nim, znaleźliśmy pewne zachowania, które pozwalają na to, że wydają się trochę niebezpieczne, jeśli zostaną niewłaściwie użyte.
Wydaje się to nieco otwarte, ale szukamy konkretnego przypadku użycia, który można zastosować w aplikacji biznesowej, która uzna to narzędzie za przydatne.
Odpowiedzi:
Możesz go użyć do naśladowania kowariancji typu zwrotu. Wyjaśnienie Erica Lipperta . Eric podaje następujący przykładowy kod:
To jest obejście.
public override Fish Contents() { ... }
nie jest legalne, mimo że jest bezpieczne.Ogólnie rzecz biorąc, należy nie używać metody ukrycia, jak to jest mylące dla konsumentów klasy (przykład specyficzna powyżej nie cierpi z tego problemu). Po prostu nazwij swoją nową metodę inną nazwą, jeśli nie chcesz zastąpić istniejącej metody.
Prawdopodobną sytuacją w świecie, w której trzeba ukryć metodę, jest to, że dostawca klasy podstawowej dodał metodę ogólną, którą już dodałeś do klasy pochodnej. Taki program skompiluje się (i wyświetli ostrzeżenia) bez nowego słowa kluczowego, ale dodanie
new
mówi: „Wiem, że moja wersja tej metody zastępuje wersję klasy podstawowej. To jest okropne i mylące, ale utknęliśmy z tym”. To wciąż lepsze niż zmuszanie klasy pochodnej do zmiany nazwy metody.Dopuszczenie, aby metoda pochodna była traktowana jako przesłonięcie, spowodowałoby problemy. Ignorując wszelkie obawy związane z implementacją kompilatora, nowa metoda różni się semantycznie od metody podstawowej, ale polimorfizm spowodowałby wywołanie nowej metody, gdy zostanie poproszony o wywołanie metody o tej samej nazwie.
Sytuację tę szczegółowo omawia w tym poście Eric Lippert.
źródło
new
bycie markerem „to jest okropne i mylące”.Myślę, że jest tam na wypadek, gdybyś potrzebował go do zrobienia czegoś, o czym nie pomyśleli projektanci języka. C # było pod wieloma względami reakcją na wczesne wersje java. Jedną z rzeczy, które zrobiła java, było bardzo wyraźne zaszufladkowanie programistów, aby wyeliminować możliwość, że programiści strzelą sobie w nogi. C # przyjął nieco inne podejście i dał programistom nieco więcej mocy, pozwalając programistom na kilka dodatkowych okazji do strzelania sobie w stopy. Jednym z przykładów jest
unsafe
słowo kluczowe. Tonew
słowo kluczowe jest inne.Teraz prawdopodobnie nie jest tak przydatny,
unsafe
ale kiedy wejdziesz w specyfikację języka, trudno jest wydostać się ze specyfikacji języka.źródło
Mówi czytelnikowi, że „celowo ukryłem implementację tej metody przez klasę podstawową”, a nie przypadkowo.
źródło
Możesz chcieć, aby poprzedni członek był dostępny pod inną nazwą:
Twoje zdrowie.
źródło
Uznałem, że jest to bardzo przydatne podczas tworzenia zestawu testów dla starszego kodu. Pozwala mi ukryć zależności zewnętrzne, takie jak zapytania do bazy danych wewnątrz metody używanej przez inne metody. Aby móc przetestować inne metody, mogę ukryć oryginalną logikę zależną od zasobów zewnętrznych, bez potrzeby dodawania wirtualnego słowa kluczowego do tych metod w klasach testowych.
źródło