Domanda

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 ritrovo con 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 riflettere...Dovrei implementare una classe DateRange?Non ne conosco uno nella 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 al modello piuttosto che viceversa.Tuttavia, non siamo vincolati ai nomi delle proprietà e saremmo disposti a scendere a compromessi con qualcosa del tipo:

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 miei metodi:

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

Non sono sicuro che un corso DateRange non mi metterà più nei guai del suo valore.Opinioni?

Domanda a margine:Mi sono persa da qualche parte una classe tupla generica per uso generale nella BCL?So che ce ne sono alcuni molto specifici che fluttuano in vari spazi dei nomi.Inquinare le mie firme dei metodi di dominio pubblico con i tipi C5 mi sembra molto, molto sporco.

È stato utile?

Soluzione

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

Ho un Range digitare MiscUtil che potrebbe interessarti - e sicuramente è semplice DateTime manipolazione.Facendo riferimento alla risposta di Marc, non ricordo se si tratta di una struttura o di una classe: ovviamente potresti cambiarla.

È bello e facile da eseguire, a causa degli imbrogli dei generici di Marc (supponendo che tu stia utilizzando almeno .NET 3.5 - è 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
}

(Ciò utilizza anche una serie 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 data in modo più appropriato rispetto all'API .NET, ma al momento non abbiamo nulla di simile a un intervallo...È una bella idea però: ho aggiunto un file richiesta di funzionalità.

Altri suggerimenti

In .NET 4.0 o superiore del Tuple <> tipo è stato aggiunto per gestire più valori.

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

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

Qualunque strada si prende, penso che si sta sicuramente prendendo l'approccio corretto. Si stanno dando un significato reale a quello che due date accoppiati insieme sono. Questo è auto-documentazione del codice e nel modo più grande, proprio nella struttura del codice.

Se lavori molto con le date, sì: un intervallo può essere utile.Questo è in realtà uno di quei casi così rari in cui tu Dovrebbe probabilmente scrivilo come a struct (immutabile).Tieni presente, tuttavia, che "Noda Time" probabilmente ti darà tutto questo e altro ancora (una volta completato).Ho già utilizzato software di pianificazione;Avevo un paio di strutture simili (per lavori leggermente diversi).

Nota: non esiste un costrutto BCL utile per questo.

Inoltre, pensa a tutti i meravigliosi metodi (e possibilmente agli operatori) che puoi centralizzare quando disponi di un intervallo;"contiene" (di un datetime?di un'altra gamma?compresi/esclusi i limiti?), "interseca", offset-by (un periodo di tempo), ecc.UN definito caso per avere un tipo che lo gestisca.Tieni presente che a livello ORM, questo è più semplice se il tuo ORM supporta valori compositi: credo che NHibernate lo faccia e possibilmente EF 4.0.

Non so di qualsiasi classe .NET nativo della natura DateRange. Il più vicino è probabilmente DateTime + TimeSpan o DateTime / DateTime combinazione.

Credo che quello che vuoi è piuttosto valida.

Come Mark e Jon già menzionate, vorrei creare questo come un valore-tipo, che è immutabile. Io opterei per la sua attuazione come una struct, e implementare le interfacce IEquatable e IComparable.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top