2012-01-24 12 views
17

Stavo scrivendo un metodo che prende il valore DateTime come uno dei suoi parametri. Ho deciso che è un parametro facoltativo, quindi sono andato avanti e ho provato a rendere DateTime.MinValue come predefinito.Perché DateTime.MinValue non può essere utilizzato come parametro opzionale in C#

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

} 

Tuttavia, questo dà un errore che:

predefinito valore di parametro per 'testVar' deve essere una costante fase di compilazione.

L'utilizzo di questo codice sembra funzionare correttamente.

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

} 

mi è stata data consiglio di utilizzare DateTime.MinValue instead of new DateTime() come è auto-documentazione. Dal new DateTime() è praticamente la stessa cosa perché non è possibile utilizzare DateTime.MinValue? Inoltre ci sarà qualche potenziale problema se lo lascio con new DateTime()?

+1

Approccio alternativo: quando è logico che un valore predefinito sia DateTime.MinValue? Mi rendo conto che è il * default * per DateTime, ma in realtà è un valore appropriato per il metodo dato? O forse se il valore non viene fornito, non dovrebbe essere semplicemente nullo? –

+0

Ho usato 'DateTime.MinValue' ovunque durante l'acquisizione di valori da SQL che era null come' DateTime' non è annullabile. 'DateTime?' È. – MadBoy

+2

questo è il punto in cui sto arrivando, ed è più applicabile qui. Se stai mappando su un database che supporta le date nullable, sembra appropriato usare date nullable nel tuo codice, e quindi per le date senza valori semplicemente essere nullo, così come sono nel tuo database. Solo un pensiero. –

risposta

11

DateTime.MinValue è definito come:

public static readonly DateTime MinValue 

Che non è la stessa di const. Poiché un valore readonly non è una costante in fase di compilazione (vale a dire il valore è non valutato in fase di compilazione), non può essere utilizzato.

Il motivo per cui l'utilizzo di new DateTime() funziona perché quell'espressione è nota in fase di compilazione. È lo stesso di scrivere default(DateTime). Ad esempio, result == true nella seguente espressione:

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

Che dire di nuovo DateTime()? – MadBoy

+0

@MadBoy Vedere le mie modifiche che risolvono questa domanda – Yuck

5

DateTime.MinValue è readonly, e come per MSDN, valori di sola lettura non sono costanti di compilazione:

La parola sola lettura è differente dalla const parola chiave. Un campo const può essere inizializzato solo alla dichiarazione del campo. Un campo di sola lettura può essere inizializzato o alla dichiarazione o in un costruttore. Pertanto, i campi di sola lettura possono avere valori diversi a seconda del costruttore utilizzato. Inoltre, mentre un campo const è una fase di compilazione costante, il campo di sola lettura può essere utilizzato per il runtime costanti

+0

E riguardo 'nuovo DateTime'? Perché funziona? Posso lasciarlo a' new DateTime'? o dovrei usare "DateTime" nullo e annullabile? – MadBoy

+0

Penso che dovresti andare con Nullable of Datetime – Magnus

+0

@Magnus Probabilmente andrò con Nullable of DateTime ma mi piacerebbe avere una spiegazione sull'intero argomento così da uscire la mia testa E sembra che tutti si concentrino su DateTime.MinValue che va bene, ma c'è un'altra parte della domanda;) – MadBoy

1

sulla base di quello che sono consapevoli del valore di default per datetime viene DateTime.MinValue quindi perché non basta usare nuovo DateTime()

+0

Che non funzionerà. I valori predefiniti devono essere costanti in fase di compilazione. 'new DateTime()' non è sicuramente una costante in fase di compilazione. –

+1

@JimMischel come per la mia domanda permette in realtà di compilare bene se uso il nuovo DateTime() .. quindi mi sto solo chiedendo/preoccupandomi che mi risparmi ad un certo punto. – MadBoy

+0

Capisco che, ma sulla base di ciò che ha affermato, sto solo partendo dal presupposto che avrebbe forse dichiarato una variabile di DateTime someDateTime = new DateTime(); questa era la mia comprensione della sua domanda e so che questo verrà compilato ... – MethodMan

4

DateTime.MinValue (e DateTime.MaxValue) sono membri public static readonly anziché costanti in fase di compilazione.

Invece di utilizzare DateTime.MinValue come impostazione predefinita, perché non utilizzare un valore DateTime nullable (DateTime?). Ciò rende il tuo intento piuttosto più chiaro del default al valore più basso possibile di datetime.

Qualcosa di simile a questo:

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 
} 

In alternativa, impostare il predefinito nel metodo corpo:

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

    DoSomethingUsefulWithTimestamp(something , dtParameter) ; 

} 
+0

Il problema è che ho DateTime.MinValue su tutto il codice e non uso nullable DateTime? affatto. Risolvere questo problema per essere coerenti attraverso il codice sarà un killer. Ovviamente potrei farlo per questa volta, ma a un certo punto potrei passare DateTime.MinValue per errore, quindi è possibile che o dovrò occuparmi di esso in codice come in controllo per entrambi se null, se DateTime.MinValue o conta per non commettere errori :) – MadBoy

3

Un'altra alternativa sarebbe quella di avere 2 Metodo sovraccarichi:

  • uno che accetta un parametro DateTime
  • One th at non utilizza il parametro DateTime

Il vantaggio di questo è che non si dovrà controllare se il parametro è nullo e sarebbe chiaro quale sia la propria intenzione. Internamente, il metodo 1 può aggiungere un valore null al database.

9

Altre risposte toccano il motivo per cui DateTime.MinValue non può essere utilizzato, non è una costante di tempo legale di compilazione. Si tratta di un campo static readonly, che potrebbe essere molto costante per quanto riguarda l'utilizzo, ma non è legalmente costante, né si adatta alle regole per ciò che può essere utilizzato come argomento predefinito. Per quanto riguarda il motivo per cui new DateTime()può essere utilizzato, vedere la sezione 10.6.1 di C# 4.0 Language Specification. bit rilevanti:

L'espressione in un default-argomento deve essere uno dei seguenti:

· una costante espressione

· espressione della forma nuovi S() dove S è un tipo di valore

· espressione del difetto forma (S) dove S è un tipo di valore

Questi risultati in un'istanza inizializzata a zero, in pratica un modello di bit di tutti gli zeri. (Vedere: Sezione 4.1.2)

Tuttavia, in questo caso, si consiglia comunque di utilizzare uno DateTime? value = null come parametro e argomento predefinito, in particolare quando rappresenta una data nullable in un database. MinValue non è l'assenza di un valore. null è.

+0

Grazie per le informazioni chiare. Vorrei che ci fosse un'opzione per accettare 2 risposte (tipo di risposta assistita). – MadBoy

0

utilizzare questa istruzione

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

Dovrebbe funzionare molto meglio. È un peccato che null non funzioni, perché avrebbe più senso.

Problemi correlati