.net using - Devo creare un oggetto DateRange?




tuple c# (5)

Alcuni dei miei oggetti di dominio contengono intervalli di date come una coppia di proprietà di data di inizio e di fine:

public class Period {
  public DateTime EffectiveDate { get; set; }
  public DateTime ThroughDate { get; set; }
}

public class Timeline {
  public DateTime StartDate { get; set; }
  public DateTime EndDate { get; set; }
}

E mi trovo molto di questo:

abstract public int Foo(DateTime startDate, DateTime endDate);
abstract public decimal Bar(DateTime startDate, DateTime endDate);
abstract public ICollection<C5.Rec<DateTime, DateTime>> FooBar(DateTime startDate, DateTime endDate);

L'ultimo mi ha fatto chiedere ... Devo implementare una classe DateRange? Non sono a conoscenza di uno nel BCL.

Nella mia esperienza, rendere la gerarchia degli oggetti più profonda spesso complica le cose. Questi oggetti vengono inviati ai report RDLC visualizzati dal controllo ReportViewer, ma questo è secondario. Piegherò la vista sul modello piuttosto che viceversa. Tuttavia, non siamo legati ai nomi delle proprietà e saremmo disposti a scendere a compromessi con qualcosa come:

public class DateRange {
  public DateTime StartDate { get; set; }
  public DateTime EndDate { get; set; }
}

Period p = new Period();
DateTime t = p.EffectiveDateRange.StartDate;

Un vantaggio di una classe DateRange sarebbe la convalida centralizzata della data di fine successiva alla data di inizio e semplificherà le firme dei metodi:

abstract public int Foo(DateRange dateRange);
abstract public decimal Bar(DateRange dateRange);
abstract public ICollection<DateRange> FooBar(DateRange dateRange);

Non sono sicuro che una classe DateRange non mi metterà in difficoltà più del suo valore. Opinioni?

Domanda a parte: mi sono perso una classe di tuple generica per uso generico nel BCL da qualche parte? So che ci sono alcuni molto specifici che fluttuano in vari spazi dei nomi. Inquinare le firme dei metodi di dominio pubblico con i tipi C5 sembra molto, molto sporco.


Answers

No, non ti sei perso una lezione di carattere generale.

Ho un tipo Range in MiscUtil cui potresti essere interessato - e certamente rende semplice la manipolazione di DateTime . Riferendomi alla risposta di Marc, non riesco a ricordare se si tratti di una struttura o di una classe - naturalmente, sarebbe il caso di cambiarla.

È bello e facile da eseguire, a causa dello shenanigans generico di Marc (supponendo che tu stia usando .NET 3.5, almeno - è fattibile con 2.0 ma non supportato al momento);

Range<DateTime> range = 19.June(1976).To(DateTime.Today);

foreach (DateTime date in range.Step(1.Days())
{
    // I was alive in this day
}

(Questo sta anche usando un sacco di metodi di estensione - più utili per i test che per la produzione.)

Per affrontare l'altro punto della risposta di Marc, Noda Time sarà sicuramente in grado di esprimere il concetto di una data in modo più appropriato rispetto all'API .NET, ma al momento non abbiamo nulla di simile a un intervallo ... È una buona idea però - Ho aggiunto una richiesta di funzionalità .


In .NET 4.0 o versione successiva è stato aggiunto il tipo Tuple <> per gestire più valori.

Con il tipo di tupla puoi definire la tua combinazione di valori al volo. Il tuo problema è molto comune ed è simile a quando una funzione vuole restituire più valori. In precedenza dovevi usare le variabili o creare una nuova classe solo per la risposta della funzione.

Tuple<DateTime, DateTime> dateRange =
    new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now);

Qualunque percorso tu faccia, penso che tu stia decisamente prendendo l'approccio corretto. Stai dando un vero significato a ciò che sono due date insieme. Questo è un codice auto-documentante e nel modo migliore, proprio nella struttura del codice.


Non conosco alcuna classe nativa .NET della natura DateRange. La più vicina è probabilmente la combinazione DateTime + TimeSpan o DateTime / DateTime.

Penso che quello che vuoi sia abbastanza sano.


Come Mark e Jon hanno già menzionato, creerei questo come valore-tipo, che è immutabile. Io sceglierei di implementarlo come una struct e implementare le interfacce IEquatable e IComparable.

Quando si utilizza un ORM come NHibernate, sarà possibile memorizzare il tipo di valore all'interno di una tabella che rappresenta un'entità.


È necessario utilizzare la classe GetRequestStream e il metodo GetRequestStream .

Here un esempio.





.net model tuples date-range