Pregunta 1:
¿Se debe a la devolución del nuevo StreamReader (nombre de archivo); dentro del bucle for? o el hecho de que no necesitas un bucle for en este caso?
El lector de flujo no tiene nada que ver con eso. El antipatrón surge debido a un claro conflicto de intenciones entre el foreachy el if:
¿Cuál es el propósito de la foreach?
Supongo que su respuesta será algo así como: "Quiero ejecutar repetidamente un código en particular"
¿Cuántos archivos esperas procesar?
Dado que solo puede tener un nombre de archivo específico (incluida la extensión) en una carpeta en particular, esto prueba que su código está destinado a encontrar un archivo aplicable.
Esto también se confirma por el hecho de que está devolviendo un valor de inmediato. En realidad no te importa una segunda partida, incluso si existiera.
Hay situaciones en las que esto no es un antipatrón.
- Si también busca en subdirectorios (
Directory.GetFiles(".", SearchOption.AllDirectories)), entonces es posible encontrar más de un archivo con el mismo nombre de archivo (incluida la extensión)
- Si busca coincidencias parciales de nombre de archivo (por ejemplo, cada archivo cuyo nombre comienza con
"Test_", o cada "*.zip"archivo.
Tenga en cuenta que ambos casos requerirían que realmente procese varias coincidencias y, por lo tanto, no devuelva un valor de inmediato.
Pregunta 2:
Para arreglar el segundo ejemplo, ¿lo volvería a escribir sin la instrucción if, y en su lugar rodearía el StreamReader con un bloque try-catch, y si arroja una FileNotFoundException lo maneja en el bloque catch en consecuencia?
Las excepciones son caras. Nunca deben usarse en lugar de una lógica de flujo adecuada. Las excepciones son, como su nombre indica, circunstancias excepcionales .
Por esa razón, no debes eliminar el if.
Según esta respuesta en SoftwareEngineering.SE :
En general, el uso de excepciones para el flujo de control es un antipatrón, con notables tos de excepciones de tos específicas de la situación y el lenguaje.
Como resumen rápido de por qué, en general, es un antipatrón:
- Las excepciones son, en esencia, declaraciones GOTO sofisticadas
- La programación con excepciones, por lo tanto, conduce a un código más difícil de leer y comprender
- La mayoría de los idiomas tienen estructuras de control existentes diseñadas para resolver sus problemas sin el uso de excepciones.
- Los argumentos para la eficiencia tienden a ser discutibles para los compiladores modernos, que tienden a optimizar con la suposición de que no se usan excepciones para el flujo de control.
Lea la discusión en el wiki de Ward para obtener información mucho más detallada.
Si necesita envolver esto en un intento / captura, depende en gran medida de su situación:
- ¿Qué tan probable es que te encuentres con una condición de carrera?
- ¿Eres capaz de manejar esta situación o quieres que este problema surja para el usuario porque no sabes cómo manejarlo?
Nada es cuestión de "usarlo siempre". Para probar mi punto:
Estudios separados han demostrado que es menos probable que te lastimes cuando usas un casco de seguridad, gafas de seguridad y chalecos antibalas.
Entonces, ¿por qué no todos llevamos este equipo de seguridad en todo momento?
La respuesta simple es porque hay inconvenientes en usarlos:
- Cuesta dinero
- Hace que tu movimiento sea más engorroso
- Puede ser bastante cálido usarlo.
Ahora estamos llegando a algún lado: hay ventajas y desventajas . En otras palabras, solo tiene sentido usar este equipo en los casos en que los profesionales superan a los contras.
- Los trabajadores de la construcción tienen muchas más probabilidades de sufrir lesiones durante su trabajo. Se benefician de un casco de seguridad.
- Los trabajadores de oficina, por otro lado, tienen muchas menos posibilidades de lesionarse. Los cascos de seguridad no valen la pena.
- Un miembro del equipo SWAT tiene muchas más probabilidades de recibir un disparo, en comparación con un empleado de oficina.
¿Debería terminar la llamada en un intento / captura? Eso depende en gran medida de si los beneficios de hacerlo superan el costo de implementarlo.
Tenga en cuenta que otros pueden argumentar que solo se necesitan unas pocas teclas para envolverlo, por lo que obviamente debe hacerse. Pero ese no es el argumento completo:
- Debe decidir qué hacer una vez que detecte la excepción.
- Si hay muchas llamadas diferentes a diferentes archivos en toda la base de código, decidir envolver uno en un intento / captura generalmente significará que debe envolver todo estos casos. Esto puede tener un efecto dramático en la cantidad de esfuerzo requerido para implementarlo.
- Es perfectamente posible que intencionalmente quiere no manejar una excepción.
- Tenga en cuenta que su aplicación tendrá que manejar la excepción en algún momento, pero eso no es necesariamente inmediatamente después de que se planteó la excepción.
Entonces la elección es tuya. ¿Hay algún beneficio en hacerlo? ¿Crees que mejora la aplicación, más que un esfuerzo costoso para implementarla?
Actualización : de un comentario que escribí a la otra respuesta, ya que creo que también es una consideración relevante para usted:
Depende mucho del contexto que lo rodea.
- Si la apertura del lector de secuencias está precedida por
if(!File.Exists) File.Create(), entonces la ausencia del archivo al abrir el lector de secuencias es realmente excepcional .
- Si el nombre de archivo se seleccionó de una lista de archivos existentes, su ausencia repentina es nuevamente excepcional .
- Si está trabajando con una cadena que aún no ha probado en el directorio; entonces la ausencia del archivo es un resultado perfectamente lógico y, por lo tanto, no excepcional .