none
Nested Parameters RRS feed

  • Question

  • Hello C# Community,

    I have an "Job" class, with many "date" parameters.  What I would like, is to be able to say :

    Job myJob = new Job();
    
    myJob.Dates.Date1 = new DateTime();
    myJob.Dates.Date2 = new DateTime();


    Right now, this is my "Job" class.

    public class Job
    {
    
    public string Name {get;set;}
    
    public DateTime Date1 {get;set;}
    public DateTime Date2 {get;set;}
    
    }

    So when I create a new instance of the object, and assign a date it's like this :

    Job myJob = new Job();
    
    myJob.Date1 = new DateTime();
    myJob.Date2 = new DateTime();

    It doesn't seem that bad with a few dates, but with 20+ my "Jobs." looks messy and complicated.

    Thoughts, opinions, ideas, comments?


    Wednesday, May 22, 2013 12:30 AM

Answers

  • In your OP you said you would like to say

    myJob.Dates.Date1 = new DateTime();

    but that at the moment you have to say

    myJob.Date1 = new DateTime();

    Is this really what you are trying to achieve?  If so, you could create another class (called something like StatutaryDates) which has properties of type DateTime with the names you desire.  The Job class would then have an instance of the StatutaryDates in it.

    public class StatutaryDate {
       public DateTime Created {get; set;}
       public DateTime Expires {get;set;}
    }
    
    public class Job {
       public string Name {get; set;}
       public StatutaryDate Dates {get; private set;}
    
       public Job() {
          Dates = new StatutaryDate();
       }
    }

    Obviously, you could initialize any dates in a StatutaryDate constructor or in the Job constructor, as required.

    But ... you could consider a different approach.  Define an enum with the names of all the different types of dates

    public enum DateType {Created, Expires, Cancelled, etc}

    Your Job class could have a private Dictionary to hold whatever dates have been specified

    var theDates = new Dictionary<DateType, DateTime>();

    You would then provide a small number of methods to get/set the dates.  Roughly,

    public class Job {
    .
    .
    .
    public void SetDate(DateType dateType, DateTime date)
    {
       theDates[dateType] = date;
    }
    
    public DateTime GetDate(DateType dateType)
    {
       return theDates.ContainsKey(dateType) ?
                 theDate[dateType] :
                 DateTime.MinValue ; // or whatever you want
    }

    If there are more common things that happen then you could create specific routines for them if you like

    public void DocCreated() { SetDate(DateType.Created, DateTime.Now); }

    You could overload the SetDate method to have just the DateType parameter which defaults to using DateTime.Now as the date.  This may be convenient if most calls actually use the current DateTime.

    You could extend the SetDate method to log somewhere that a particular user has set a particular date to a value.  If desired, you could extend SetDate to throw an exception if the calling code attempts to set a date for the second time (overwriting information) if that was considered a mistake.

    You could have a method HasDateBeenSet(DateType dateType) which returns the value of ContainsKey if you wanted to know whether a particular date has been set or not.

    If there are many dates to be recorded but a large percentage of them do not get commonly used then having the Dictionary to only hold those that have been set may provide a memory saving.


    Paul Linton

    Wednesday, May 22, 2013 2:55 AM

All replies

  • Use an array or list of dates.
    Wednesday, May 22, 2013 12:36 AM
  • Do Date1 and Date13 mean something to you or your developers, or, would it just be better to have a List<Date> Dates property?  In other words, have you considered a collection of Date objects as the property to the Job class, so that you can be flexible in your assignments and use of the class?

    Mike

    Wednesday, May 22, 2013 12:37 AM
  • The dates actually have much more descriptive names.  Things like "Expiration Date" "Creation Date".  Right now we just predicate the property with "Date".

    In the end, it would really look like this :

    Job myJob = new Job();
    
    myJob.Dates.Due = new DateTime();
    myJob.Dates.Created = new DateTime();
    myJob.Dates.Expires = new DateTime();
    // etc, etc forever.
    Wednesday, May 22, 2013 2:11 AM
  • Do Date1 and Date13 mean something to you or your developers, or, would it just be better to have a List<Date> Dates property?  In other words, have you considered a collection of Date objects as the property to the Job class, so that you can be flexible in your assignments and use of the class?

    Mike

    I think we want to be more "static" in the assignments of dates.  This particular software has very strict dates (dealing with law) so they are named and never change.
    Wednesday, May 22, 2013 2:13 AM
  • I'm not sure that I understand what the problem is, but if you are just looking for a way to initialise the dates without having to do it every time you instantiate a job, you could do it like this...

    public class JobDates
    {
        DateTime due = new DateTime();
        public DateTime Due { get {return due;} set {due = value;}}
    
        DateTime created = new DateTime();
        public DateTime Created{ get {return created;} set { created = value; } }
    
        // etc. etc.
    }
    
    
    public class Job
    {
        public string Name{get; set;}
    
        public JobDates Dates{get; set;}
    }
    Wednesday, May 22, 2013 2:41 AM
  • In your OP you said you would like to say

    myJob.Dates.Date1 = new DateTime();

    but that at the moment you have to say

    myJob.Date1 = new DateTime();

    Is this really what you are trying to achieve?  If so, you could create another class (called something like StatutaryDates) which has properties of type DateTime with the names you desire.  The Job class would then have an instance of the StatutaryDates in it.

    public class StatutaryDate {
       public DateTime Created {get; set;}
       public DateTime Expires {get;set;}
    }
    
    public class Job {
       public string Name {get; set;}
       public StatutaryDate Dates {get; private set;}
    
       public Job() {
          Dates = new StatutaryDate();
       }
    }

    Obviously, you could initialize any dates in a StatutaryDate constructor or in the Job constructor, as required.

    But ... you could consider a different approach.  Define an enum with the names of all the different types of dates

    public enum DateType {Created, Expires, Cancelled, etc}

    Your Job class could have a private Dictionary to hold whatever dates have been specified

    var theDates = new Dictionary<DateType, DateTime>();

    You would then provide a small number of methods to get/set the dates.  Roughly,

    public class Job {
    .
    .
    .
    public void SetDate(DateType dateType, DateTime date)
    {
       theDates[dateType] = date;
    }
    
    public DateTime GetDate(DateType dateType)
    {
       return theDates.ContainsKey(dateType) ?
                 theDate[dateType] :
                 DateTime.MinValue ; // or whatever you want
    }

    If there are more common things that happen then you could create specific routines for them if you like

    public void DocCreated() { SetDate(DateType.Created, DateTime.Now); }

    You could overload the SetDate method to have just the DateType parameter which defaults to using DateTime.Now as the date.  This may be convenient if most calls actually use the current DateTime.

    You could extend the SetDate method to log somewhere that a particular user has set a particular date to a value.  If desired, you could extend SetDate to throw an exception if the calling code attempts to set a date for the second time (overwriting information) if that was considered a mistake.

    You could have a method HasDateBeenSet(DateType dateType) which returns the value of ContainsKey if you wanted to know whether a particular date has been set or not.

    If there are many dates to be recorded but a large percentage of them do not get commonly used then having the Dictionary to only hold those that have been set may provide a memory saving.


    Paul Linton

    Wednesday, May 22, 2013 2:55 AM
  • Also note that since DateTime is a “struct”, you do not have to assign the ‘new DateTime()’ initial value. It is already initialized to ‘1/01/0001 00:00:00’.

    Wednesday, May 22, 2013 5:44 AM