Inizializza una data di nascita con un DateTime o tre numeri interi?

0

Recentemente ho posto questa domanda: link . Ho intenzione di evitare un oggetto valore DateOfBirth . Invece sto pensando di usare un alias di tipo. Ho alcune opzioni riguardo al mio costruttore:

Opzione 1

using DateOfBirth=System.DateTime;
DateOfBirth DateOfBirth;    

public Person (DateOfBirth dateOfBirth)
{
     if (dateOfBirth.TimeOfDay.TotalSeconds > 0)
         throw new ArgumentException("Date of birth cannot contain a time.")
     DateOfBirth = dateOfBirth;
}

Opzione 2

DateOfBirth DateOfBirth;   
public Person(int day, int month, int year)
{
   //Validation to make sure day, month and year are valid.
   DateOfBirth = new DateOfBirth(year,month,day);
}

Sto cercando di decidere, quale opzione scegliere. La convalida per l'opzione due potrebbe essere piuttosto complessa perché alcuni mesi hanno un numero diverso di giorni. Pertanto spero che l'opzione 1 sia adatta a questo.

Inoltre, dovrei usare gli alias di tipo nei miei Test di unità o semplicemente fare riferimento ad essi come il tipo primitivo, cioè l'ora della data?

    
posta w0051977 03.02.2018 - 16:25
fonte

2 risposte

4

La tua opzione è una cattiva idea. Se stai utilizzando un DateTime , chiamalo DateTime .

public Person (DateTime dateOfBirth)

è molto chiaro, mentre la tua variante con using è criptica.

Se vuoi essere in grado di avere regole aziendali specifiche per una data di nascita (che è ragionevole, dato che molti valori di DateTime non saranno necessariamente date di nascita valide), l'opzione migliore potrebbe essere quella di ereditare da% codice%. Sfortunatamente, non sarai in grado di farlo, dal momento che DateTime è un DateTime .

Pertanto, crea la tua classe e inserisci un campo struct al suo interno. L'implementazione di confronti in questo caso è piuttosto semplice, poiché è possibile delegare tutto il lavoro al DateTime sottostante. Devi ancora gestire DateTime e == .

All'interno di questa classe, sarai in grado di eseguire la convalida dell'input (all'interno del costruttore), per estrarre i dati di cui hai bisogno (ovvero mantenere la data e rilasciare l'ora), oltre a garantire che i chiamanti possano ottenere solo il informazioni di cui hanno bisogno e non potranno mai accedere al sottostante campo Equals .

    
risposta data 03.02.2018 - 16:58
fonte
2

Penso che ci sia un'altra opzione. Dal momento che ritieni che il concetto di componente data senza tempo abbia un valore per il tuo dominio, allora ciò che è importante qui è che la convalida avviene non appena hai la data , piuttosto che in attesa di convalida all'interno del costruttore Person . Per fare ciò dovresti usare una semplice classe wrapper come segue:

class DateOnly {
    public readonly DateTime Value;
    public DateOnly ( DateTime value ) {
       if ( value.Date != value )
           throw new IllegalArgumentException ( "time component not allowed" );
       Value = value;
    }
    public DateOnly ( int year, int month, int day ) {
        Value = new DateTime ( year, month, day );
    }
}


class Person {
     Person ( DateOnly birthDate ) { }
}
    
risposta data 03.02.2018 - 16:58
fonte

Leggi altre domande sui tag