简体   繁体   中英

Overloaded constructor chain

Original Question

Consider the following scenario:


public abstract class Foo
{
    public string Name { get; set; }

    public Foo()
    {
        this.Name = string.Empty;
    }
    public Foo(string name)
    {
        this.Name = name;
    }
}
public class Bar : Foo
{
    public int Amount { get; set; }

    public Bar()
        : base()
    {
        this.Amount = 0;
    }
    public Bar(string name)
        : base(name)
    {
        this.Amount = 0;
    }
    public Bar(string name, int amount) 
        : base(name)
    {
        this.Amount = amount;
    }
}

Is there any more elegant means of chaining the construction so that there is no duplication of code between them? In this example, I end up having to replicate the code to set the value of the Bar.Amount property to the value of the amount parameter in the second constructor. As the number of variables in the class increases, the permutations for construction could get quite complex. It just sort of smells funny.

I did sift through the first couple of pages of my search on this issue, but I wasn't getting specific results; sorry if this is old hat.

Thanks in advance.

UPDATE

So then I was thinking about it backwards, and the following should be my approach:


public abstract class Foo
{
    public string Name { get; set; }
    public string Description { get; set; }

    public Foo()
        : this(string.Empty, string.Empty) { }

    public Foo(string name)
        : this(name, string.Empty) { }

    public Foo(string name, string description)
    {
        this.Name = name;
        this.Description = description;
    }
}
public class Bar : Foo
{
    public int Amount { get; set; }
    public bool IsAwesome { get; set; }
    public string Comment { get; set; }

    public Bar()
        : this(string.Empty, string.Empty, 0, false, string.Empty) { }

    public Bar(string name)
        : this(name, string.Empty, 0, false, string.Empty) { }

    public Bar(string name, int amount)
        : this(name, string.Empty, amount, false, string.Empty) { }

    public Bar(string name, string description, int amount, bool isAwesome, string comment)
        : base(name, description)
    {
        this.Amount = amount;
        this.IsAwesome = isAwesome;
        this.Comment = comment;
    }
}

Thanks so much for the response.

Yes, you can call one constructor from another in C# by using the this keyword. This is often used to simulate default parameters. Example:

public class Bar : Foo
{
    public int Amount { get; set; }

    public Bar() : this(String.Empty) {}
    public Bar(string name): this(name, 0) {}
    public Bar(string name, int amount) : base(name)
    {
        this.Amount = amount;
    }
}
public class Bar : Foo {
  public int Amount { get; set; } 

  public Bar() : this(null, 0) { }

  public Bar(string name) : this(name, 0) { }

  public Bar(string name, int amount) : base(name){
    this.Amount = amount;    
  }
}
public class Bar : Foo {
    public int Amount { get; set; }

    public Bar() : this(0) { }
    public Bar(int amount) : this(String.Empty, amount) { }
    public Bar(string name) : this(name, 0) { }
    public Bar(string name, int amount) : base(name) {
        this.Amount = amount;
    }
}

or

public class Bar : Foo {
    public int Amount { get; set; }

    public Bar() : this(String.Empty, 0) { }
    public Bar(string name) : this(name, 0) { }
    public Bar(string name, int amount) : base(name) {
        this.Amount = amount;
    }
}

The assumption with constructor chaining is that there is one constructor that does the real work, and other constructor chain to that one. Usually it's to set up optional parameters; the constructor that "does it all" takes the full parameter list. Other constructors have a shorter parameter list, and pass defaults when chaining.

public class Foo : Bar
{
    private bool whyFoo;

    public Foo() : this(true)
    {
    }
    public Foo(bool why) : base(why, false)
    {
        whyFoo = why;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM