Whether you're talking about constructors or not, overloading's pretty limited, and when you start to run up against its limits, that's a hint that it's not the right tool for the job.
It's worth looking at a well-designed API that uses overloading to get a sense of what kind of job the tool is good for. XmlReader.Create
is a good example: It supports twelve different overloads. Twelve! And yet, it's actually completely sensible: when you look at them all, they boil down to what would, in Python, be a single calling signature with optional parameters:
XmlReader.Create(input [, settings [, parser_context]])
input
, to this method, can be a string containing a URL or filename, a TextReader
, or a Stream
. But irrespective of its data type, it's still fundamentally the same thing: the source of the data that the XmlReader
is going to read.
Now let's look at your case. Forget about data types for a moment. There's clearly some functional difference between a status
and an idCode
in your application. Your form is going to behave one way if it's given a status
and another if it's given an idCode
. The API that you're proposing conceals this functional difference. It should be illuminating it.
I would first consider the simplest possible approach, which uses no overloads at all:
TheForm(string idCode, string status)
Make your constructor throw an exception if both values are provided (or if both are null). Note that they're mutually exclusive in the documentation. Call it a day.
My second choice would be:
enum FormType
{
IdCode,
Status
};
TheForm(FormType type, string data)
This is less concise, but it has the very great merit of making the fact that this method supports multiple mutually-exclusive modes explicit.
I called that enum FormType
because it seemed like a sensible name, given what I know so far, and the fact that this method's a constructor. But whenever you contemplate creating an enum to determine the type of an instance, you should at least consider the possibility that you should really be creating a type to determine the type of an instance:
class TheFormWhatUsesIdCode : TheForm {...}
class TheFormWhatUsesStatus : TheForm {...}
The functional difference between idCode
and status
probably relates to a functional difference between a form instantiated with idCode
and a form instantiated with status
. And that strongly suggests that they should be subclasses.
In all of this analysis, I've never once considered the possibility of doing what you actually asked for, which is to provide multiple overloads. I don't think overloading is the right tool for this job. If idCode
were an int
and status
were a string
I still wouldn't think that overloading were the right tool for this job, though I probably wouldn't have ended up noticing it until I had a lot of code I needed to refactor.