I have a class with overloaded constructor (C#) It can be initialized in few ways, and some parameters are optional – so in result – there is a confusing bunch of constructors
new Object(StrA, StrB, ObjA)
new Object(StrA, StgB, ObjB, StrC)
new Object(StrA, StrB, ObjA, StrD)
new Object(StrA, StrB, ObjB, StrC, StrD)
new Object(StrA, StrB, StrE, ObjA)
new Object(StrA, StrB, StrE, ObjB)
new Object(StrA, StrB, StrE, ObjA, StrC)
new Object(StrA, StrB, StrE, ObjB, StrC, StrD)
I see a two ways to improve situation
a) create a structure to hold optional parameters
new Config(StrA, StrB, StrD, StrE)
new Object(Config, ObjA)
new Object(Config, ObjB, StrC)
b) set optional parameters as properties
A = new Object(ObjA)
A.StrA = some;
A.StrB = some;
A.StrD = some;
A.StrE = some;
Which is the best way?
And is such code refactoring necessary – the previous code maintainer says that “while intellisense used, complexity of constructor doesn’t matter – it always possible to check tips and select the correct one”
Yes, I would refactor this. IntelliSense is only so much helpful, and staring at a 5-argument constructor which takes 3 seemingly random strings trying to figure out which one means what is not going to improve code readability any. In VB (or C# 4.0), I’d still go with constructor, but use named arguments. For C# 3.0, I’d make a separate class to hold the initialization info:
and then take a single argument of that type in constructor:
and use object initializer when invoking it:
The main advantage of this compared to just having properties in
Objectis that this pattern guarantees thatObjectwill be properly initialized as soon as it is constructed. With properties on object itself, it will be in invalid state until client sets them all correctly, and you’ll have to validate that on pretty much every call.This pattern is actually used in .NET FCL – see
XmlReader/XmlReaderSettingsfor an example of it.