Pytanie 1:
Czy to z powodu zwrócenia nowego StreamReadera (nazwa pliku); wewnątrz pętli for? lub fakt, że w tym przypadku nie potrzebujesz pętli for?
Czytnik strumieniowy nie ma z tym nic wspólnego. Anty-wzór wyłania się z powodu wyraźnego konfliktu pomiędzy intencją foreach
a if
:
Jaki jest cel tego foreach
?
Zakładam, że twoja odpowiedź będzie taka: „Chcę wielokrotnie wykonywać określony fragment kodu”
Ile plików zamierzasz przetworzyć?
Ponieważ możesz mieć tylko jedną konkretną nazwę pliku (łącznie z rozszerzeniem) w określonym folderze, dowodzi to, że Twój kod ma znaleźć jeden odpowiedni plik.
Potwierdza to również fakt, że zwracasz wartość natychmiast. Tak naprawdę nie obchodzi cię drugi mecz, nawet gdyby miał on istnieć.
Są sytuacje, w których nie jest to anty-wzór.
- Jeśli zajrzysz również do podkatalogów (
Directory.GetFiles(".", SearchOption.AllDirectories)
), możesz znaleźć więcej niż jeden plik o tej samej nazwie (łącznie z rozszerzeniem)
- Jeśli szukasz częściowych dopasowań nazw plików (np. Każdego pliku, którego nazwa zaczyna się od
"Test_"
, lub każdego "*.zip"
pliku.
Zauważ, że oba te przypadki wymagałyby przetworzenia wielu dopasowań i dlatego nie zwracałyby natychmiast wartości.
Pytanie 2:
Aby naprawić drugi przykład, czy napisałbyś go ponownie bez instrukcji if, a zamiast tego otoczyłeś StreamReader blokiem try-catch, a jeśli zgłosi wyjątek FileNotFoundException, odpowiednio poradzisz sobie z nim w bloku catch?
Wyjątki są drogie. Nigdy nie należy ich używać zamiast właściwej logiki przepływu. Wyjątki są, ponieważ ich nazwa sugeruje wyjątkowe okoliczności.
Z tego powodu nie należy usuwać pliku if
.
Zgodnie z odpowiedzią na SoftwareEngineering.SE :
Zasadniczo stosowanie wyjątków w przepływie kontrolnym jest anty-wzorcem, z kaszlem wyjątkowym zależnym od konkretnej sytuacji i języka.
Krótko podsumowując, dlaczego ogólnie jest to anty-wzór:
- Wyjątki stanowią w istocie wyrafinowane wypowiedzi GOTO
- Programowanie z wyjątkami prowadzi zatem do trudniejszego do odczytania i zrozumienia kodu
- Większość języków ma istniejące struktury kontrolne zaprojektowane w celu rozwiązywania problemów bez użycia wyjątków
- Argumenty dotyczące wydajności wydają się być dyskusyjne w przypadku nowoczesnych kompilatorów, które mają tendencję do optymalizacji przy założeniu, że wyjątki nie są używane do sterowania przepływem.
Przeczytaj dyskusję na wiki Warda, aby uzyskać więcej szczegółowych informacji.
To, czy chcesz zawinąć to w try / catch, zależy w dużej mierze od twojej sytuacji:
- Jak prawdopodobne jest, że spotkasz się z wyścigiem?
- Czy jesteś w stanie poradzić sobie z tą sytuacją, czy chcesz, aby problem ten pojawił się u użytkownika, ponieważ nie wiesz, jak sobie z tym poradzić.
Nic nie jest nigdy kwestią „zawsze używaj”. Aby udowodnić swój punkt widzenia:
Oddzielne badania wykazały, że mniej prawdopodobne jest, że odniesiesz obrażenia, gdy będziesz nosić kask ochronny, okulary ochronne i kamizelki kuloodporne.
Dlaczego więc nie wszyscy nosimy ten sprzęt bezpieczeństwa przez cały czas?
Prosta odpowiedź polega na tym, że noszenie ich ma wady:
- Kosztuje pieniądze
- Sprawia, że Twój ruch jest bardziej niewygodny
- Noszenie go może być dość ciepłe.
Teraz do czegoś dochodzimy: są plusy i minusy . Innymi słowy, sensowne jest noszenie tego sprzętu tylko w przypadkach, gdy profesjonaliści przeważają nad wadami.
- Pracownicy budowlani są znacznie bardziej narażeni na obrażenia podczas pracy. Korzystają z kasku ochronnego.
- Z drugiej strony pracownicy biurowi mają znacznie mniejsze szanse na odniesienie obrażeń. Hełmy ochronne nie są tego warte.
- Członek zespołu SWAT jest znacznie bardziej narażony na zastrzelenie w porównaniu z pracownikiem biurowym.
Czy powinieneś zawinąć połączenie w try / catch? To bardzo zależy od tego, czy korzyści z tego wynikające przeważają koszty jego wdrożenia.
Pamiętaj, że inni mogą argumentować, że wystarczy kilka naciśnięć klawiszy, aby go owinąć, więc oczywiście należy to zrobić. Ale to nie jest cały argument:
- Musisz zdecydować, co zrobić, gdy złapiesz wyjątek.
- Jeśli istnieje wiele różnych wywołań do różnych plików w całej bazie kodu, decyzja o zawinięciu jednego w try / catch na ogół oznacza, że musisz owinąć wszystkie te przypadki. Może to mieć ogromny wpływ na nakład pracy związany z jego wdrożeniem.
- Jest całkiem możliwe, że celowo chcą nie obsłużyć wyjątek.
- Pamiętaj, że aplikacja będzie musiała obsłużyć wyjątek w pewnym momencie, ale niekoniecznie natychmiast po zgłoszeniu wyjątku.
Więc wybór należy do ciebie. Czy jest z tego korzyść? Czy uważasz, że poprawia ona aplikację, bardziej niż kosztowne wdrożenie?
Aktualizacja - od komentarza, który napisałem, do drugiej odpowiedzi, ponieważ uważam, że jest to również istotne dla ciebie:
Bardzo zależy to od otaczającego kontekstu.
- Jeśli otwarcie czytnika strumieniowego jest poprzedzone
if(!File.Exists) File.Create()
, to brak pliku podczas otwierania czytnika strumieniowego jest rzeczywiście wyjątkowy .
- Jeśli nazwa pliku została wybrana z listy istniejących plików, jej nagły brak znów jest wyjątkowy .
- Jeśli pracujesz z ciągiem, który nie został jeszcze przetestowany względem katalogu; wtedy brak pliku jest wynikiem całkowicie logicznym, a zatem nie wyjątkowym .