Answered by:
Nested Parameters

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?
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
- Proposed as answer by Ed Price - MSFTMicrosoft employee Wednesday, May 22, 2013 5:35 AM
- Marked as answer by GarrettHampton Wednesday, May 22, 2013 3:18 PM
All replies
-
-
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
-
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.
-
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'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;} }
- Proposed as answer by Ed Price - MSFTMicrosoft employee Wednesday, May 22, 2013 5:35 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
- Proposed as answer by Ed Price - MSFTMicrosoft employee Wednesday, May 22, 2013 5:35 AM
- Marked as answer by GarrettHampton Wednesday, May 22, 2013 3:18 PM
-