Is there a way to denote the best constructor to use in C#, so that a developer knows which to pick by default?
Say you have a class:
public class MyClass
{
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId, DateTime mySpecialDate, DateTime myOtherDate, bool isProduction)
: this(controlNumber1, controlNumber1, companyNumber, recordId, mySpecialDate, myOtherDate)
{
IsProduction = isProduction;
}
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId, DateTime mySpecialDate, DateTime myOtherDate)
: this(requestReferenceId, controlNumber1, companyNumber, recordId)
{
MySpecialDate = mySpecialDate;
MyOtherDate = myOtherDate;
}
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId, DateTime mySpecialDate)
: this(requestReferenceId, controlNumber1, companyNumber, recordId)
{
MySpecialDate = mySpecialDate;
MyOtherDate = mySpecialDate;
}
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId)
: this()
{
if (controlNumber1 == 0)
throw new ArgumentException("Invalid Parameter: cannot be 0", "controlNumber1");
if (recordId == 0)
throw new ArgumentException("Invalid Parameter: cannot be 0", "recordId");
if (string.IsNullOrWhiteSpace(companyNumber))
throw new ArgumentException("Invalid Parameter: cannot be empty", "companyNumber");
RequestReferenceId = requestReferenceId == 0 ? 1 : requestReferenceId;
ControlNumber1 = controlNumber1;
ControlNumber2 = controlNumber1;
RecordId = recordId;
CompanyNumber = companyNumber;
}
public MyClass()
{
MyStringProperty = string.Empty;
MySpecialDate = DateTime.Now;
MyOtherDate = MySpecialDate;
RequestReferenceId = 1;
ControlNumber1 = 1;
ControlNumber2 = 1;
TransactionNumber = 1;
ReferenceNumber = 1;
IsProduction = true;
}
public string MyStringProperty { get; set; }
public DateTime MySpecialDate { get; set; }
public DateTime MyOtherDate { get; set; }
public bool IsProduction { get; set; }
public int RequestReferenceId { get; set; }
public int ControlNumber1 { get; set; }
public int ControlNumber2 { get; set; }
public int TransactionNumber { get; set; }
public int ReferenceNumber { get; set; }
public string CompanyNumber { get; set; }
public int RecordId { get; set; }
public string TraceNumber
{
get { return string.Format("{0}-{1}", ControlNumber2, RecordId)}
}
}
And want to inform the developer that the version below is the recommended one to use:
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId, DateTime mySpecialDate)
is there something in C# like below to do this? I know you can make up an attribute in-house, but is there a C# feature to do this? Am I missing something basic..oops... C#?
[Recommended]
public MyClass(int requestReferenceId, int controlNumber1, string companyNumber, int recordId, DateTime mySpecialDate)
Firstly, I'd advise you to chain your constructors the other way round - make the ones with fewer parameters chain (possibly indirectly) to a single constructor with all the parameters, and make that the only one which sets anything. That saves your assignments being scattered all over the place as they are at the moment
Secondly, I'd consider using optional parameters instead of all that overloading:
public MyClass(
int requestReferenceId,
int controlNumber1,
string companyNumber,
int recordId,
DateTime mySpecialDate, = default(DateTime)
DateTime myOtherDate = default(DateTime),
bool isProduction = false)
{
...
}
Then you only have a single constructor, so you don't have to "recommend" anything. Developers have to specify arguments for all the required parameters, but can choose which of the optional parameters they specify arguments for. Don't forget that different developers may be in different contexts - if you've recommended the overload without the isProduction
parameter but they want to specify the isProduction
parameter, that causes a conflict between your advice and what they need to achieve.
See more on this question at Stackoverflow