Two dates as properties in C#

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();
        }
    }
Jon Skeet
people
quotationmark

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;
}

people

See more on this question at Stackoverflow