Search code examples
c#oopstructreadability

Is it right to use a struct instead of giving a constructor 8 arguments?


I was just thinking,

if I need to write a constructor for let's say an Apartment class, and the apartment class has several of properties such as ApartmentSize, NumberOfBedrooms, NumberOfShowers, CurrentMarketValue, PurchasePrice etc.

Will it be more readable to create a struct that is called, let's say, ApartmentProperties and to have all of the above properties as members of this struct, so when I need to construct an apartment, all the constructor requires is just this struct?

If not, what would be a more elegant way of doing it?


Solution

  • Seems a bit circular. You've got an object whose constructor needs all these values, so you're creating an object to contain them. So now you've got a struct that needs all these values... how do you create the struct?

    You're proposing this:

    ApartmentProperties props = new ApartmentProperties(size, numBedrooms, numShowers, marketValue, purchasePrice);
    Apartment apt = new Apartment(props);
    

    It seems no different to doing this:

    Apartment apt = new Apartment(size, numBedrooms, numShowers, marketValue, purchasePrice);
    

    If this is the only time you're using the ApartmentProperties struct, and all you're doing is putting all these values into it, passing it to a constructor, and then pulling them out again, then it feels unnecessary. It's just one more object to think about.

    In the comments it's been suggested that if you don't like having so many parameters on the constructor, then you could do this:

    Apartment apt = new Apartment();
    apt.Size = size;
    apt.NumBedrooms = numBedrooms;
    apt.Numshowers = numShowers;
    apt.MarketValue = marketValue;
    apt.PurchasePrice = purchasePrice;
    

    I'm not a huge fan of this approach. Now your constructor is smaller and tidier, yes, but all you've done is move the logic that was neatly wrapped up inside it out to wherever you're calling it from. This makes the calling code responsible for making sure that all the properties are properly assigned. I'd advise leaving the assignments in the constructor - it just lets you assume that an Apartment object has its properties assigned because you know the constructor will have done it.

    Of course, there is a middle ground. You could take out some of the constructor parameters, leaving only those that must be there. For example, an apartment always has a size, a number of bedrooms, and a number of showers, but you might not know its current value or purchase price - perhaps someone's been living there a while and haven't had a valuation recently. In that case, you could cut the constructor down to just three parameters, and allow the calling code to assign the others if they're known. Or better yet, overload the constructor with varying numbers of parameters. Just make sure you have some way of telling for sure whether a value has been assigned (for example, there may be some weird cases in which a sale price of zero is valid, but perhaps you know that -1 is never going to be valid). If you need to be really sure, use Nullable<T> and return null if it's not been assigned yet.