Domanda 1:
È a causa della restituzione di nuovo StreamReader (nome file); all'interno del ciclo for? o il fatto che non hai bisogno di un ciclo for in questo caso?
Lo streamreader non ha nulla a che fare con esso. L'anti-pattern emerge a causa di un chiaro conflitto di intenzioni tra il foreach
e il if
:
Qual è lo scopo di foreach
?
Presumo che la tua risposta sarà qualcosa del tipo: "Voglio eseguire ripetutamente un particolare pezzo di codice"
Quanti file ti aspetti di elaborare?
Poiché è possibile avere un solo nome file specifico (inclusa l'estensione) in una determinata cartella, ciò dimostra che il codice è destinato a trovare un file applicabile.
Ciò è confermato anche dal fatto che stai restituendo immediatamente un valore. In realtà non ti importa di una seconda partita, anche se dovesse esistere.
Ci sono situazioni in cui questo non è un anti-schema.
- Se si guarda anche nelle sottodirectory (
Directory.GetFiles(".", SearchOption.AllDirectories)
), è possibile trovare più di un file con lo stesso nome file (inclusa l'estensione)
- Se cerchi corrispondenze di nome file parziali (ad es. Ogni file il cui nome inizia con
"Test_"
, o ogni "*.zip"
file.
Nota che entrambi questi casi richiederebbero di elaborare effettivamente più corrispondenze e quindi di non restituire immediatamente un valore.
Domanda 2:
Per correggere il secondo esempio, lo riscriveresti senza l'istruzione if e invece circonderesti StreamReader con un blocco try-catch e se genera un FileNotFoundException lo gestirai nel blocco catch di conseguenza?
Le eccezioni sono costose. Non dovrebbero mai essere usati al posto della corretta logica di flusso. Le eccezioni sono, poiché il loro nome suggerisce circostanze eccezionali .
Per questo motivo, non dovresti rimuovere il file if
.
Secondo questa risposta su SoftwareEngineering.SE :
Generalmente, l'uso delle eccezioni per il flusso di controllo è un modello anti-pattern, con notevoli tosse con eccezioni specifiche per la situazione e la lingua.
Come una breve sintesi del perché, generalmente, è un anti-pattern:
- Le eccezioni sono, in sostanza, sofisticate dichiarazioni GOTO
- La programmazione con eccezioni, quindi, rende più difficile leggere e comprendere il codice
- La maggior parte delle lingue ha strutture di controllo esistenti progettate per risolvere i tuoi problemi senza l'uso di eccezioni
- Gli argomenti per l'efficienza tendono ad essere discutibili per i compilatori moderni, che tendono ad ottimizzare ipotizzando che le eccezioni non vengano utilizzate per il flusso di controllo.
Leggi la discussione sul wiki di Ward per informazioni molto più approfondite.
Se hai bisogno di avvolgerlo in un tentativo / cattura, dipende fortemente dalla tua situazione:
- Quanto è probabile che si verifichi una condizione di gara?
- Sei effettivamente in grado di gestire questa situazione o vuoi che questo problema si risolva in una bolla perché non sai come gestirla.
Nulla è mai questione di "usarlo sempre". Per dimostrare il mio punto:
Studi separati hanno dimostrato che è meno probabile che ti faccia male quando indossi un casco di sicurezza, occhiali di sicurezza e giubbotti antiproiettile.
Quindi perché non indossiamo sempre questa attrezzatura di sicurezza?
La semplice risposta è perché ci sono degli svantaggi nell'indossarli:
- Costa denaro
- Rende il tuo movimento più ingombrante
- Può essere abbastanza caldo da indossare.
Ora stiamo arrivando da qualche parte: ci sono pro e contro . In altre parole, ha senso indossare questa attrezzatura solo nei casi in cui i professionisti superano i contro.
- Gli operai edili hanno molte più probabilità di subire un infortunio durante il loro lavoro. Beneficiano di un casco di sicurezza.
- D'altro canto, gli impiegati hanno una probabilità molto più bassa di ferirsi. I caschi di sicurezza non ne valgono la pena.
- Un membro del team SWAT ha molte più probabilità di essere colpito, rispetto a un impiegato.
Dovresti concludere la chiamata in un tentativo / cattura? Ciò dipende molto dal fatto che i vantaggi di farlo superino i costi di attuazione.
Nota che altri potrebbero obiettare che bastano pochi tasti per avvolgerlo, quindi ovviamente dovrebbe essere fatto. Ma questo non è l'intero argomento:
- Devi decidere cosa fare una volta rilevata l'eccezione.
- Se ci sono molte chiamate diverse a file diversi in tutta la base di codice, decidere di racchiuderne uno in un tentativo / cattura significa generalmente che è necessario racchiudere tutti questi casi. Questo può avere un effetto drammatico sulla quantità di sforzo richiesto per implementarlo.
- È perfettamente possibile che tu non voglia gestire un'eccezione intenzionalmente .
- Si noti che l'applicazione dovrà gestire l'eccezione ad un certo punto, ma ciò non è necessariamente immediatamente dopo che l'eccezione è stata sollevata.
Quindi la scelta è tua. C'è un vantaggio nel farlo? Pensi che migliora l'applicazione, più che un dispendio di costi per implementarla?
Aggiornamento - Da un commento che ho scritto sull'altra risposta, poiché penso che sia una considerazione rilevante anche per te:
Dipende molto dal contesto circostante.
- Se l'apertura dello streamreader è preceduta da
if(!File.Exists) File.Create()
, l'assenza del file all'apertura dello streamreader è davvero eccezionale .
- Se il nome file è stato selezionato da un elenco di file esistenti, la sua improvvisa assenza è di nuovo eccezionale .
- Se stai lavorando con una stringa che non hai ancora testato sulla directory; quindi l'assenza del file è un risultato perfettamente logico e quindi non eccezionale .