john wilkens
john wilkens

Reputation: 61

Constructor chaining or use named/optional parameters

I'm a very new programmer and understand we want to minimize code redundancy so when we update we can make as few changes as possible and also minimize errors.

So I have a Student class that I want overloaded constructor so If I do back chaining it's like this.

 public class Student
{
    string name;
    int Id;

    public Student()
    {
    }
    public Student(string name)
    {
        this.name = name;
    }
    public Student(string name, int Id) :this(name)
    {
        this.Id = Id;

But this is apparently bad because we want all the code in one constructor for what reason? Ease of reading?

    public Student() : this(null, 0)
    { }
    public Student(string name) : this(name, 0)
    { }
    public Student(string name, int Id) 
    {
        this.name = name;
        this.Id = Id;
    }

If I do this forward chaining then what happens if we add a new field like string major? If I do forward chaining then I create a new overloaded constructor with the added field. But now I have to change all the other constructors to call the new one. If I do backwards chaining I just create a new constructor and call the previous overloaded one.

    public Student(string name, int Id, string major):this(name, Id)
    {
        this.major=major;
    } 

This seems like it follows OOP better but all examples in my text book show forward chaining and don't say why I shouldn't use back chaining.

If I used named/optional parameters it's even easier.

    public Student(string name = null, int Id = 0, string major = null)
    {
        this.name = name;
        this.Id = Id;
        this.major = major;
    }

And if I need another field I just have to edit the one and only constructor. This seems to follow OOP principles the best or am I mistaken? It at least eliminates code duplication the most. My assignment was to "implement the student class following the principles of OOP". I know all these are valid but is one way the best/accepted way of coding constructors? Are there shortcomings with named/optional params that I'm missing? As a beginner it's very confusing that there's so many ways to code this.

Upvotes: 6

Views: 2189

Answers (4)

Pablo H
Pablo H

Reputation: 659

This is a partial answer. Your "backwards chaining", with one constructor setting some parameter(s) then calling another constructor for the rest, is very reasonable/sensible for normal functions: one function does part of the work, then calls another function for some other work, and so on.

But for public constructors, any one of them can be called by client code, expecting to get a fully constructed object, fully initialized. Some constructors in your example leave members uninitialized (unless what you want is the default value for the type).

As an alternative, you can have private constructors.

Upvotes: 0

Cheng Chen
Cheng Chen

Reputation: 43531

There is no best way, because they are different, each of them has advantages and disadvantages.

Independent constructors and chained constructors are available since C# 1.0, under most circumstances we use chained constructors but sometimes we have to use the former if the two constructors has totally different things to handle.

class Student
{
    public Student()
    {
        DoSomething();
    }

    public Student(string name)
    {
        this.Name = name;
        DoAnotherThing();
    }
}

Comparing with optional parameters constructor, the above two are much longer, but to be honest, they are much safer. Consider the following case:

public class Student
{
    public Student(string firstName = null, string lastName = null)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

//it's working fine
//var danny = new Student("danny", "chen");

//as the business grows a lot of students need a middle name
public Student(string firstName = null, string middleName = null, string lastName = null)
{
    this.FirstName = firstName;
    this.MiddleName = middleName;
    this.LastName = lastName;
}

//for a better sequence the programmer adds middleName between the existing two, bang!

Another difference between them is using reflection. Optional parameters will not generate more constructors for you, and the default values will not be applied if you are invoking the constructor using reflection.

Upvotes: 3

Edgars Pivovarenoks
Edgars Pivovarenoks

Reputation: 1684

I suggest looking deeper about this assumption :

"But this is apparently bad because we want all the code in one constructor for what reason"

There is Fluent Interface Pattern that puts these things apart, also I can not strongly argue that this directly translates for constructors.

customer
    .NameOfCustomer("Shiv")
    .Bornon("12/3/1075")
    .StaysAt("Mumbai");

Illustrative implementation :

public class Customer
{
    public string FullName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Address { get; set; }

    public Customer NameOfCustomer(string name)
    {
        this.FullName = name;
        return this;
    }

    public Customer BornOn(DateTime dateOfBirth)
    {
        this.DateOfBirth = dateOfBirth;
        return this;
    }

    public Customer StaysAt(string address)
    {
        this.Address = address;
        return this;
    }
} 

Example source

Upvotes: 1

Alastair Brown
Alastair Brown

Reputation: 1616

I know all these are valid but is one way the best/accepted way of coding constructors?

Not to the best of my knowledge - you have many options. Your colleagues are the best people to talk to to reach a consensus. C# is becoming a very rich language, and that means that there will be many different ways to achieve the same thing.

Are there shortcomings with named/optional params that I'm missing?

Not to the best of my knowledge. Personally I think this is the best solution, but others may differ.

As a beginner it's very confusing that there's so many ways to code this.

Welcome to programming. There's millions of us programmers, and we're all busy adding complexity to the world!

Upvotes: 1

Related Questions