.net - collection - using tuple




Devo creare un oggetto DateRange? (4)

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.


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à.


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.


Se lavori molto con le date, sì, un intervallo può essere utile. Questo è in realtà uno di quei casi così raro in cui dovresti probabilmente scriverlo come una struct (immutabile). Nota, comunque, che "Noda Time" probabilmente ti darà tutto questo e altro (quando è completo). Ho già fatto software di programmazione prima; Ho avuto un paio di tali strutture (per lavori leggermente diversi).

Nota, non esiste un pratico costrutto BCL per questo.

Inoltre, pensa a tutti i metodi meravigliosi (e possibilmente agli operatori) che puoi centralizzare quando hai una portata; "contiene" (di un datetime? di un altro intervallo? includendo / escludendo i limiti?), "interseca", offset-da (un intervallo di tempo), ecc. Un caso preciso per avere un tipo per gestirlo. Nota che a livello di ORM, questo è più facile se il tuo ORM supporta valori compositi - credo che NHibernate lo faccia, e possibilmente EF 4.0.





date-range