I want to have two simple properties: the start date and the end date. I want to put a constraint that the start date must be before the end date. The problem arises when modifying both values - they may (together!) make a new, correct pair, but at the moment of adding them, there is an error. Simple example:
start = 5;
end = 10;
new_start = 20;
new_end = 30;
start = new_start; // error!
end = new_end;
That is why I introduced the third property. The thing is - the code looks terrible (especially the .Item1, .Item2 thing).
Is there a way to do it in a better way in C#?
private DateTime start;
private DateTime end;
public DateTime Start { get { return start; } }
public DateTime End { get { return end; } }
public Tuple<DateTime, DateTime> Dates
{
get
{
return new Tuple<DateTime, DateTime>(Start, End);
}
set
{
if (value.Item1 <= value.Item2)
{
start = value.Item1;
end = value.Item2;
}
else
throw new InvalidDates();
}
}
Well, you might think about whether it would make sense to have a type which represents a start/end combination. A sort of... Interval
. (Yes, this is a not-so-subtle plug for Noda Time, which makes date/time handling generally better anyway. But you could create your own Interval
struct for DateTime
if you wanted...) Then you can have a single property to combine the start/end times, in a way which is guaranteed to be valid.
But if you really want to keep them as separate properties, I'd go with a simple setter. I wouldn't create a separate exception for this though - just use ArgumentException
:
public void SetDates(DateTime start, DateTime end)
{
if (end < start)
{
throw new ArgumentException("End must be at or after start", "end");
}
this.start = start;
this.end = end;
}
See more on this question at Stackoverflow