2012-01-24 24 views
17

Estaba escribiendo un método que toma el valor DateTime como uno de sus parámetros. Decidí que era un parámetro opcional, así que continué e intenté hacer DateTime.MinValue como predeterminado.Por qué DateTime.MinValue no se puede usar como parámetro opcional en C#

private void test(string something, DateTime testVar = DateTime.MinValue) { 

} 

Sin embargo, esto da un error que:

valor de parámetro por defecto de 'testvar' debe ser una constante de tiempo de compilación.

El uso de este código parece funcionar bien.

private void test(string something, DateTime testVar = new DateTime()) { 

} 

me dieron consejos para usar DateTime.MinValue instead of new DateTime() ya que es auto-documentado. Desde new DateTime() es básicamente lo mismo que DateTime.MinValue no se puede utilizar? ¿También habrá algún problema potencial si lo dejo con new DateTime()?

+1

Enfoque alternativo: ¿Cuándo tiene sentido que un valor predeterminado sea DateTime.MinValue? Me doy cuenta de que es * default * para DateTime, pero ¿es realmente un valor apropiado para el método dado? O tal vez si no se proporciona el valor, ¿no debería simplemente ser nulo? –

+0

He estado usando 'DateTime.MinValue' en todas partes al obtener valores de SQL que era nulo ya que' DateTime' no puede contener nulos. 'DateTime?' Es. – MadBoy

+2

ese es el punto al que estoy llegando, y es más aplicable aquí. Si está mapeando a una base de datos que admita fechas anulables, parece apropiado usar fechas anulables en su código, y luego las fechas sin valores simplemente serán nulas, ya que están en su base de datos. Simplemente un pensamiento. –

Respuesta

11

DateTime.MinValue se define como:

public static readonly DateTime MinValue 

que no es el mismo que const. Como el valor readonly no es una constante en tiempo de compilación (es decir, el valor es no evaluado en tiempo de compilación), no se puede utilizar.

El motivo por el que se usa new DateTime() es porque esa expresión es conocida en tiempo de compilación. Es lo mismo que escribir default(DateTime). Por ejemplo, result == true en la siguiente expresión:

var result = new DateTime() == default(DateTime); 
+0

¿Qué hay de nuevo DateTime()? – MadBoy

+0

@MadBoy Vea mis ediciones que aborda esa pregunta. – Yuck

5

DateTime.MinValue es readonly, y según MSDN, los valores de sólo lectura no están en tiempo de compilación constantes:

La palabra clave de sólo lectura es diferente de la const palabra clave. Un campo const solo se puede inicializar en la declaración del campo. Un campo de solo lectura se puede inicializar en la declaración o en un constructor. Por lo tanto, los campos de solo lectura pueden tener diferentes valores según el constructor utilizado. Asimismo, si bien un campo const es una constante en tiempo de compilación, el campo de sólo lectura se puede utilizar para el tiempo de ejecución constantes de

+0

¿Qué pasa con 'new DateTime'? ¿Por qué funciona? ¿Puedo dejarlo en' dateTime' nuevo o debería usar nulo y nulo 'DateTime? ' – MadBoy

+0

Definitivamente creo que deberías ir con Nullable of Datetime – Magnus

+0

@Magnus Probablemente vaya con Nullable of DateTime pero me gustaría obtener una explicación sobre el tema completo para que salga de mi cabeza. E parece que uno se centra en DateTime.MinValue, que está bien, pero hay otra parte de la pregunta;) – MadBoy

1

basado en lo que soy consciente de valor por defecto para DateTime es DateTime.MinValue ¿por qué no sólo tiene que utilizar la nueva DateTime()

+0

Eso no funcionará. Los valores predeterminados tienen que ser constantes de tiempo de compilación. 'new DateTime()' definitivamente no es una constante en tiempo de compilación. –

+1

@JimMischel según mi pregunta, realmente permite compilar muy bien si uso el nuevo DateTime() .. así que me pregunto/me preocupo porque me devolverá el arma en algún momento. – MadBoy

+0

Entiendo eso, pero basado en lo que dijo, solo estoy suponiendo que tal vez haya declarado una variable de DateTime someDateTime = new DateTime(); esa fue mi comprensión de su pregunta y sé que esto compilará ... – MethodMan

4

DateTime.MinValue (y DateTime.MaxValue) son miembros public static readonly en lugar de constantes de tiempo de compilación.

En lugar de usar DateTime.MinValue como valor predeterminado, ¿por qué no utilizar un DateTime que se puede anular (DateTime?). Eso hace que su intento sea más claro que el valor por defecto al valor más bajo posible de datetime.

Algo como esto:

private void test(string something, DateTime? testVar = null) 
{ 
    if (testVar.HasValue) 
    { 
    DoSomethingUsefulWithTimestamp(something , testVar.Value) ; 
    } 
    else 
    { 
    DoSomethingElseWithoutTimestamp(something) ; 
    } 
    return ; 
} 

private void DoSomethingUsefulWithTimestamp(string something , DateTime dt) 
{ 
    ... // something useful 
} 
private void DoSomethingElseWithoutTimestamp(string something) 
{ 
    ... // something useful 
} 

Alternativamente, establecer su defecto en el cuerpo del método:

private void test(string something, DateTime? testVar = null) 
{ 
    DateTime dtParameter = testVar ?? DateTime.MinValue ; 

    DoSomethingUsefulWithTimestamp(something , dtParameter) ; 

} 
+0

¿El problema es que tengo DateTime.MinValue en todo el código y no uso DateTime con nulos? en absoluto. Arreglar esto para ser coherente en todo el código será un asesino. Por supuesto, podría hacerlo por una vez, pero puedo pasar DateTime.MinValue por accidente en algún momento, así que es posible que tenga que ocuparme de ello en el código como verificación de ambos si es nulo, si DateTime.MinValue o contar para no cometer errores :) – MadBoy

3

Otra alternativa sería tener 2 sobrecargas de método:

  • uno que toma un parámetro de DateTime
  • Uno at no toma el parámetro DateTime

La ventaja de esto es que no tendría que comprobar si el parámetro es nulo, y quedaría claro cuál es su intención. Internamente, el método 1 puede agregar un valor nulo a la base de datos.

9

Otras respuestas sobre por qué DateTime.MinValue no se puede utilizar, no es una constante de tiempo de compilación legal. Es un campo static readonly, que bien podría ser constante en cuanto al uso, pero no es legalmente constante, ni se ajusta a las reglas de lo que se puede utilizar como argumento predeterminado. En cuanto a por qué new DateTime()se puede usar, vea la sección 10.6.1 del C# 4.0 Language Specification. los bits pertinentes:

La expresión en una forma predeterminada-argumento debe ser una de las siguientes:

· una constante-expresión

· una expresión de la forma de nuevos S() donde S es un tipo de valor

· una expresión de la forma predeterminada forma (S) donde S es un tipo de valor

Estos resultados en una instancia inicializada cero, básicamente un patrón de bits de todos los ceros. (Consulte: Sección 4.1.2)

Sin embargo, en este caso, todavía recomiendo usar un DateTime? value = null como parámetro y argumento predeterminado, particularmente cuando representa una fecha anulable en una base de datos. MinValue no es la ausencia de un valor. null es.

+0

Gracias por la información clara. Desearía que hubiera una opción para aceptar 2 respuestas (tipo de respuesta asistida). – MadBoy

0

Utilice esta declaración

private void test(string something, DateTime testVar = new DateTime()) { 
    if (testVar != new DateTime()) 
    { 
     DoSomethingUsefulWithTimestamp(something , testVar.Value) ; 
    } 
    else 
    { 
     DoSomethingElseWithoutTimestamp(something) ; 
    } 
} 

Se debe trabajar mucho mejor. Es un fastidio que null no funciona, porque tendría más sentido.

Cuestiones relacionadas