FAQ: Basic Classes and Objects - Overloading Constructors

This community-built FAQ covers the “Overloading Constructors” exercise from the lesson “Basic Classes and Objects”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn C#

FAQs on the exercise Overloading Constructors

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in #get-help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to #get-help and #community:tips-and-resources. If you are wanting feedback or inspiration for a project, check out #project.

Looking for motivation to keep learning? Join our wider discussions in #community

Learn more about how to use this guide.

Found a bug? Report it online, or post in #community:Codecademy-Bug-Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

I’m using the overload from the first example.


public Forest(int area, string country = "Unknown")
{
  this.Area = area;
  this.Country = country;
}

Here’s how.

using System;

public class Program
{
	static void Main(string[] args)
	{
		Forest f = new Forest(800, "Africa");
		Console.WriteLine(f.Area);
		Console.WriteLine(f.Country);

		Forest f2 = new Forest(400);
		Console.WriteLine(f2.Area);
		Console.WriteLine(f2.Country);
	}

	class Forest
  {

    public int Area { get; set; }
    public string Country { get; set; }

    public Forest(int area, string country)
    { 
      this.Area = area;
      this.Country = country;
    }

    // constructors is default values ---> It doesn't work
    public Forest(int area, string country = "Unknown")
    {
      this.Area = area;
      this.Country = country;
    }

  }

}

I have as an answer

main.cs(29,12): error CS0111: A member `Program.Forest.Forest(int, string)'is already defined. Rename this member or use different parameter types
main.cs(22,12): (Location of the symbol related to previous error)
Compilation failed: 1 error(s), 0 warnings
compiler exit status 1

Unlike when I use the second method, which works.


using System;

public class Program
{
	static void Main(string[] args)
	{
		Forest f = new Forest(800, "Africa");
		Console.WriteLine(f.Area);
		Console.WriteLine(f.Country);

		Forest f2 = new Forest(400);
		Console.WriteLine(f2.Area);
		Console.WriteLine(f2.Country);
	}

	class Forest
  {

    public int Area { get; set; }
    public string Country { get; set; }

    public Forest(int area, string country)
    { 
      this.Area = area;
      this.Country = country;
    }

    // It's working
    public Forest(int area) : this(area, "Unknown")
    { 
      Console.WriteLine("Country property not specified. Value defaulted to 'Unknown'.");
    }

  }

}
800
Africa
Country property not specified. Value defaulted to 'Unknown'.
400
Unknown

On point 3: When you run the code, you should see the warning message and “Unknown” printed to the console. Why are these two things printed?

This is exactly what happens. However, WHY ARE these two things printed out? Left for me to figure out? Don’t leave me hanging like this Codecademy :frowning:

4 Likes

I believe the issue here is that you don’t actually need to have 2 separate constructors when using the default argument method. Try removing the first constructor (the one where you do not use a default value for the country field). You are trying to use the same parameters for 2 different constructor methods so the program doesn’t know which to choose. “Rename this member or use different parameter types” from the error message lead me to this conclusion.

1 Like

@tag0472869507 is right, this is the issue.

You have to understand how the C# picks the correct overload (for any method not just the constructor).
It looks at the method’s signature. The signature is the number of parameters and the types of the parameters. There are a few other things that matter too, such as the order of the parameters and any keywords (such as ref). It will compare the arguments passed in and see if it can find a signature that matches.

So the signatures for your two Forest constructors are int, string and int, string. Obviously, it cannot know if you intend to use the default value constructor or not unless you omit the country parameter, but if you do pass in and int and a string it has not way to know which one you want it to use.

What you are after is constructor chaining:

public class Forest
{
    public int Area { get; set; }
    public string Country { get; set; }
    private const string _unknownCountry = "Unknown";
						 
    // this(area, "Unknown") is calling the other constructor that matches this signature and runs first.
    public Forest(int area): this(area, _unknownCountry)
    {
       // This is ran after the other constructor
        Console.WriteLine($"Country property not specified. Value defaulted to '{_unknownCountry}'.");
    }

    public Forest(int area, string country)
    {
        this.Area = area;
        this.Country = country;
    }
}
1 Like

This is the example provided in the introduction:

public Forest(int area, string country)
{ 
  this.Area = area;
  this.Country = country;
}

public Forest(int area) : this(country, "Unknown")
{ 
  Console.WriteLine("Country property not specified. Value defaulted to 'Unknown'.");
}

I believe it should be

public Forest(int area) : this(area, "Unknown")

Instead of “country” - as country is the value being called as “unknown”

This really confused me for ages while trying to follow this example. Suggest that is corrected unless there’s something I’m missing?

6 Likes

I just want to elaborate on the answer given here. This lesson caused quite a bit of confusion, but I think I understand it now and think it could use more explanation. Here’s the code with my explanation:

public class Forest
{
    /* omitted code */
    
    /* if a new instance of Forest is called with one parameter, C# uses this constructor.
    (int area) refers to the parameters passed into this particular overload.
    this(area, _unknownCountry) calls another Forest constructor that has the parameters area (an int), and _unknownCountry (a string).
    essentially, this constructor passes area and _unknownCountry into the constructor with two parameters, hence the name "constructor chaining". */
    public Forest(int area): this(area, _unknownCountry)
    {
        // after the second constructor is called, this code runs.
        Console.WriteLine($"Country property not specified. Value defaulted to '{_unknownCountry}'.");
    }

    // the above code is basically this:
    public Forest(int area)
    {
      Forest(area, _unknownCountry);
    }

    //which would call this constructor
    public Forest(int area, string country)
    {
        this.Area = area;
        this.Country = country;
    }
}

Theoretically, you could chain these indefinitely, building recursively. For example:

public class Forest
{
  /* fields, parameters, etc. */

  private const string _unknown = "unknown";

  public Forest() : this(0)
  {
    Console.WriteLine("no properties specified, defaulting to 0");
  }

  public Forest(int area) : this (area, unknown)
  {
    if (area != 0) {
      Console.WriteLine("only area specified, defaulting others to \"unknown\"");
    }
  }

  /* etc etc for other parameters */

  public Forest(int area, string country, int trees, string name)
  {
    this.Area = area;
    this.Country = country;
    this.Trees = trees;
    this.Name = name;
  }
}

tl;dr: Using : this() is equivalent to using Forest(area, _unknownCountry), because this loops back to the Forest class. Feel free to make any additions/corrections/edits as needed. Hope this helps!

1 Like

The reason for the chaining syntax - you can’t actually call another constructor from inside a constructor, like you can with regular methods. It’s the same general idea, though.

This is the best explanation of how this() works and that developers made a mistake in material explanation