2011-10-20 16 views
22

Normalmente, se ho un tipo nullable per un parametro opzionale, inserisco null come valore predefinito. In questo modo so che se il valore è nullo, il chiamante non vuole specificare alcun valore per quello.Quale dovrebbe essere il valore predefinito in un parametro opzionale DateTime?

public void Foo(string text, string text2= null); 

Se il parametro è normalmente un numero intero positivo, posso usare un numero negativo

public void Foo(string text, int index=-1); 

Come su DateTime? Non è annullabile e (per quanto ne so) non ha un numero senza significato che non può essere un input vero neanche (come -1 per numero intero positivo). O c'è? Cosa useresti in questa situazione?

So anche che posso usare il tipo nullable DateTime, ma questo significa che il chiamante del metodo dovrà usare Nullable e non solo per passare semplicemente un DateTime.

+0

possibile duplicato di [C# 4.0: Posso utilizzare un TimeSpan come parametro facoltativo con un valore predefinito?] (Http://stackoverflow.com/questions/2168798/c-sharp-4-0-can-i- use-a-timespan-as-an-optional-parametro-con-un-valore-predefinito) – nawfal

risposta

31

È possibile effettuare i tipi di valore annullabile usando l'operatore ? in C#:

DateTime? myDate = null;

Da questo, è possibile rendere il parametro opzionale:

void Foo(DateTime? myDate = null) 
{ 
} 

Further reading on Nullable Types.

Questo è tuttavia, non è l'unico modo per skinare il gatto, puoi usare default(DateTime), comunque tu u non è possibile utilizzare DateTime.MinValue, MaxValue o Now in parametri facoltativi perché non sono costanti di tempo di compilazione.

Ovviamente, non è necessario utilizzare parametri opzionali, è possibile utilizzare metodi sovraccaricati se si desidera utilizzare Min, Max o Ora.

void Foo() 
{ 
    Foo(DateTime.MinValue); 
} 

void Foo(DateTime d) 
{ 
} 

Se vuoi andare eccessivo (beh, forse non eccessivo, un sacco di motivi validi per fare questo), allora si potrebbe definire un nuovo tipo di data che capisce quando si ha un valore:

class SmarterDateTime 
{ 
    public bool IsSet { get; set; } 

    // Wrapper around DateTime etc excluded. 
} 

Per quanto riguarda quello che dovrebbe essere il valore predefinito, è possibile scegliere di fare in modo che qualsiasi data rappresenti un valore predefinito se lo si desidera, ma per cose come i parametri facoltativi si avranno dei limiti.

Personalmente, tendo ad usare DateTime.MinValue.

+0

Lo so, ma questo è un po 'indesiderabile, perché il codice del chiamante dovrà chiamarlo con un valore Null pure –

+1

@LouisRhys : Non esplicitamente non lo faranno - c'è una conversione implicita da 'DateTime' a' DateTime? '. –

+0

@JonSkeet @adam c'è? Tuttavia, ricordo che a volte trovo situazioni in cui mi aspetto che il codice funzioni con un 'DateTime' ma non funzioni con un' DateTime? '(Non sono sicuro di quale fosse il codice, però) –

1
// This is the best way to null out the DateTime. 
    // 
    DateTime dateTime2 = DateTime.MinValue; 
+3

Ciò non "annulla" un DateTime. È ancora un valore valido Come distinguere tra * deliberatamente * specificando quel valore e uno che è "assente"? –

13

default (DateTime) - default operatore è destinato Si

+1

qual è il valore effettivo di esso? –

+2

Per chiunque altro si chieda, il valore effettivo è: '1-1-0001 0: 00: 00' – natli

+0

È equivalente a' DateTime.MinValue' (Midnight il primo giorno del primo mese del primo anno). – Kjartan

3

Se si utilizza il Nullable i chiamanti della vostra funzione può solo passare un DateTime regolare ad essa, in modo da non notare una cosa:) ci sono operatori impliciti che lo farà per voi

Se si desidera impostare un default nella funzione che si può fare:

public void Foo(DateTime? value = null) 
{ 
    if (value == null) 
    { 
     value = ... // default 
    } 
} 
4

controllo del parametro dateTime default, valore di s sarebbe 1/1/0001 12:00:00 AM,

private void M(Int32 x = 9, String s = “A”, DateTimedt = default(DateTime), Guidguid = new Guid()) { 
Console.WriteLine(“x={0}, s={1}, dt={2}, guid={3}”, x, s, dt, guid); 
} 
1

si potrebbe considerare l'uso del sovraccarico valore DateTime.MinValue e l'uso.

6

Alla domanda "quale può essere un valore predefinito per un DateTime" la risposta deve essere: è possibile utilizzare solo default(DateTime). Questo perché il valore di default deve essere const ed entrambi DateTime.MinValue e DateTime.MaxValue sono solo static readonly, ma nota che

default(DateTime) == DateTime.MinValue 

fino al Kind.

Se si desidera è possibile implementare un sovraccarico con un parametro in meno (DateTime) e da tale sovraccarico chiamare il metodo "main" passando il valore desiderato.

Ma come scritto da altri, il problema è che hai scritto le premesse sbagliate.

No, DateTime (come quasi tutti i ValueType s. Quasi tutti perché Nullable<Nullable<int>> è illegale, anche mentre Nullable<T> è un ValueType) è annullabile. Nullable<DateTime> o DateTime? (stessa cosa)

Anche lo int sono annullabili, sai? int? :-)

2

frammento di codice dichiarazione

public DateTime method1() 
{ 

    if (condition) 

    return new DateTime(2007, 5, 30, 11, 32, 00); 

    else 

    return default(DateTime); 

} 

Il valore di default sarà inizializzare un tipo di valore per il suo valore di default. Nel caso di un valore datetime, questo valore viene anche esposto come proprietà statica denominata DateTime.MinValue. Se si utilizza C# 1.0, l'istruzione "default (DateTime)" sarebbe equivalente a "DateTime.MinValue". È possibile utilizzare questo valore speciale come una sorta di valore "indicatore", nel senso che se viene restituito indica un datetime non valido.

Se si utilizza C# 2.0 ancora una volta, è anche possibile utilizzare quello che viene chiamato un tipo nullable, e in realtà tornare NULL, come mostrato nel seguente esempio

frammento di codice

public DateTime? method2() 
{ 

    if (condition) 

    return new DateTime(2007, 5, 30, 11, 32, 00); 

    else 

    return null; 

} 
+0

Usando MVC, avevo un DateTime come facoltativo, ma la funzione che stavo chiamando per provare e convertire in un datetime non funzionava. Aggiungere il? al tipo di ritorno Funzione totalmente fisso .. GRAZIE! –

5

DateTime.MinValue sarà il valore predefinito.

0

Dipende dal caso d'uso.

Qualsiasi che non corrisponderanno dati reali funzionerà, ma che dipende dalla vostra uso di esso (in un modo fa -1 per gli interi, dal momento che è perfettamente buon intero solo per uso di esso che è uno fosse solo gli interi positivi hanno senso).

Se si invia una data minima (interessata a tutti gli utenti successivi), verrà eseguita una data precedente alla data più recente e il codice come .Where(f -> f.When > myDate) funzionerà senza dover cercare quel caso speciale.

Allo stesso modo con le date massime in ordine inverso (qualsiasi data che sarebbe successiva all'ultima data ragionevole).

Altrimenti, basta evitare l'uso di valori predefiniti interamente e sovraccaricare invece.

+0

di "overload invece" intendi ripetere il metodo body in entrambi i metodi? –

+0

Idealmente il più possibile sarebbe condiviso da uno che chiama l'altro o da entrambi chiamando un metodo privato con la maggior parte del codice. Il punto in cui si trova l'equilibrio dipende da cosa stai facendo in questi metodi. –

+0

Sì, sono d'accordo, ma se uno chiama l'altro o entrambi chiamano lo stesso metodo, dobbiamo ancora risolvere il problema originale, no? –

Problemi correlati