2012-06-08 21 views
21

Un viejo colega de trabajo solía citar a su padre acerca de las herramientas, "Tienes que ser más inteligente que eso".¿Realmente quisiera devolver la fecha mínima?

En el siguiente código, Resharper me dice: "El valor asignado no se utiliza en ninguna ruta de ejecución" (apuntando a la primera línea). Si acepto su oferta de ayuda, dt no tiene asignado un valor ("hoy").

¿Es este un caso donde "tengo que ser más inteligente que eso" e ignorar su advertencia, o es este un caso donde la herramienta es más inteligente que yo, y simplemente no lo estoy entendiendo?

Mi opinión sobre la situación es que si falla la instrucción if, se devuelve la fecha actual (el valor predeterminado que quiero), pero si acepto las "demandas" de Resharper, se devolverá el valor predeterminado para Datetime, que es la fecha mínima, que supongo que es algo así como 7/4/1776 o 1/1/0000 más o menos.

DateTime dt = DateTime.Now; 
if (!(DateTime.TryParse(substr, out dt))) { 
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) { 
     if (dtpDlgForm.ShowDialog() == DialogResult.OK) { 
      dt = dtpDlgForm.ReturnVal; 
     } 
    } 
} 
return dt; 
+8

Este es un caso en el que le sugiero que utilice varias devoluciones. Es más obvio si reemplaza la última línea con 'return DateTime.Now' y la línea en el medio usando' return dtpDlgForm.ReturnVal'. –

Respuesta

23

Su destinados lógica permite tres posibles valores de retorno de DateTime (en orden de preferencia):

  1. El valor analizado de substr.
  2. El valor seleccionado del cuadro de diálogo.
  3. La fecha y hora actual.

Puede implementar esta lógica por tener return declaraciones separadas que se ejecuta cuando su condición tiene éxito:

DateTime dt; 
if (DateTime.TryParse(substr, out dt)) 
    return dt; 

using (var dtpDlgForm = new ReturnDate(
    "Please select the Date that the file was created:")) 
{ 
    if (dtpDlgForm.ShowDialog() == DialogResult.OK) 
     return dtpDlgForm.ReturnVal; 
} 

return DateTime.Now; 

Editar: Para obtener una explicación sobre por qué no se debe asignar un valor a una variable que se utilizará como un parámetro out, consulte Mark Byers’s answer.

+2

Gracias; todas las respuestas fueron geniales. Marqué esto como "el" correcto, porque incluso si la fecha no está confirmada por el nombre del archivo, y el usuario cierra el formulario de "diálogo" solicitándole la fecha con un resultado de diálogo que no sea "OK", sino que devuelve "hoy" en lugar de 12/7/1941 o siempre. –

+0

Pequeño punto de dificultad: la línea tryParse necesita otra right paren en lugar de punto y coma. –

+0

@ClayShannon: como Mike Bantegui [mencionado anteriormente] (http://stackoverflow.com/questions/10952470/would-i-really-want-to-return-the-minimum-date/10952537 # comment14295586_10952470), este es un caso donde pueden ser preferibles múltiples declaraciones 'return' ya que simplifican el flujo del método; simplemente puede suponer que la ejecución del método se detendrá tan pronto como cualquier condición' 'DateTime'-determinante tenga éxito. Gracias por señalando el error tipográfico "TryParse"; ahora f ixed. – Douglas

53

La respuesta que admitan muestre lo que debe estar haciendo, pero no explica por qué ReSharper se queja en el primer lugar. Dado que esta explicación podría ser útil para otros que se encuentran a su pregunta, aquí está:

Usted debe seguir el consejo de ReSharper y cambiar la primera línea a:

DateTime dt; 

Esto declara la variable dt pero no lo hace asignarle cualquier valor. No es necesario asignar un valor aquí porque definitivamente se asignará en la siguiente línea debido al out keyword. A partir de la documentación:

Aunque variables pasadas como argumentos out no tienen que ser inicializado antes de ser aprobada, se requiere el método llamado para asignar un valor antes de que el método devuelve.

Énfasis mío. Asignar el valor DateTime.Now es innecesario y engañoso porque este valor nunca se usará.

Mi opinión sobre la situación es que si la sentencia if falla, la fecha actual se devuelve

Eso no es lo que hace el código. Desde el documentation:

resultado: Cuando devuelve este método contiene el valor DateTime equivalente a la fecha y hora que figura en s, si la conversión tuvo éxito, o MinValue si la conversión no.

Con el código que envió si el análisis sintáctico falla, entonces dt contendrá el valor DateTime.MinValue y no el valor DateTime.Now que ha asignado.

+0

+1 Muy buena explicación. ¡En este tipo de situación estaría agradecido de tener a ReSharper de mi lado! Necesito pasar por todos mis usos de TryParse ahora ... :( – surfen

20

Es porque está asignando un valor a dt y luego lo pasa como out param.Si una variable se pasa como un parámetro de salida:

  • Se debe tener asignado un valor dentro de esa función antes de ser utilizado dentro de ella
  • Se debe tener asignado un valor antes de que la función devuelve

en su caso, se puede solucionar el mensaje del mensaje de ReSharper cambiando su primera línea a:

DateTime dt; 

Mi opinión sobre la situación es que si la instrucción if falla, se devuelve la fecha actual

Esto no es cierto. Siempre volverá DateTime.MinValue, independientemente del valor del objeto DateTime se pasa en

De MSDN - DateTime.TryParse(string, out DateTime):.

resultado

Tipo: System.DateTime%

Cuando este método devuelve, [resultado] contiene el valor de fecha y hora equivalente a la fecha y hora que figura en s, si la conversión tuvo éxito, o MinValue si la conversión falló. La conversión falla si el parámetro s es nulo, es una cadena vacía ("") o no contiene contiene una representación de cadena válida de una fecha y hora. Este parámetro se pasa sin inicializar.

(Énfasis añadido)

8

Un parámetro out siempre tiene un valor asignado. Siempre se garantiza que la función llamada le asigna un valor antes de regresar. Por lo tanto, sobrescribirá el valor asignado inicialmente en cualquier caso.

7

El punto aquí es sobre el uso out parameter modifier:

Aunque variables pasadas como fuera argumentos no tienen que ser inicializado antes de ser aprobada, se requiere que el método llamado para asignar un valor antes de que el método devuelve.

DateTime.TryParse asignará un valor predeterminado a dt de todos modos, y si no puede analizar substr, la dt resultante tendrá el valor de la fecha y hora como mínimo.

3
DateTime.TryParse(substr, out dt); 

puede devolver falso pero todavía se modificará dt. Tratará de completar dt lo mejor que pueda, inicializando algunos de los valores de la mejor manera posible. Cuando se utiliza el modificador out en C#, le está diciendo al programa de inicializarlo, y usted no debe esperar para retener el valor que se pasa en.

Lo que podría hacer es

DateTime dt; 
if (!(DateTime.TryParse(substr, out dt))) { 
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) { 
     if (dtpDlgForm.ShowDialog() == DialogResult.OK) { 
      dt = dtpDlgForm.ReturnVal; 
     } 
     else { 
      dt = DateTime.Now; 
     } 
    } 
} 

return dt; 
+0

Creo que su código volverá hoy si el TryParse tiene éxito. Eso no es correcto, si TryParse tiene éxito, se debe devolver el valor analizado. – comecme

+0

Dios mío, tienes toda la razón. Cambié mi respuesta para reflejar esto. –

3

Este código haría la advertencia se va. Pero creo que la respuesta de Douglas es más fácil de leer.

DateTime dt; 
if (!(DateTime.TryParse(substr, out dt))) { 
    dt = DateTime.Now; 
    using (var dtpDlgForm = new ReturnDate("Please select the Date that the file was created:")) { 
     if (dtpDlgForm.ShowDialog() == DialogResult.OK) { 
      dt = dtpDlgForm.ReturnVal; 
     } 
    } 
} 
return dt; 
Cuestiones relacionadas