Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 809
john wilkens Avatar asked Jun 02 '16 03:06

john wilkens


1 Answers

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.

like image 125
Cheng Chen Avatar answered Sep 18 '22 17:09

Cheng Chen