3

I have a class that extends a base class. The base class is more generic, and thus needs more parameters. The derived class is a specific type of base class, and thus only needs one of the two parameters the base class needs in its constructor (the derived class can provide the base class with the second parameter, but needs to do some processing first).

Is it possible to have a constructor in the derived class that then invokes the base classes constructor?

I'm aware I could just use : base(int a, int b) if the parameters were passed in directly, but I don't think I can do this since I need to process the second variable before calling the base class constructor.

class Foo {
    private int c;

    public Foo(int a, int b) {
        c = a + b;
    }
}

class Bar : Foo {
    public Bar(int a, bool plusOrMinus) {
        if (plusOrMinus) {
            Foo(a, 5); // calling base class constructor- AFTER processing
        } else {
            Foo(a, -5); // calling base class constructor- AFTER processing
        }
    }
}
8
  • You can't do that. Consider a different approach and design. Commented Oct 28, 2011 at 16:58
  • You could have another constructor in Foo that takes plusOrMinus. Commented Oct 28, 2011 at 16:59
  • 1
    Hmm. Dunno if this works, but I think you can do some tricks like public Bar(int a, bool isPositive) : base(a, isPositive ? 5 : -5) {}. Commented Oct 28, 2011 at 17:00
  • I have almost same question before stackoverflow.com/questions/3423978/… Commented Oct 28, 2011 at 17:05
  • 1
    Putting logic in constructors can be a dangerous game. Use with caution. Commented Oct 28, 2011 at 17:09

6 Answers 6

4

One way to do this is to use the ternary operator

public Bar(int a, bool plusOrMinos) : base(a, plusOrMinus ? 5 : -5) {
  ...
}

For more complex conditionals though you should switch to a static factory method

private Bar(int a, int b) : base(a, b) {
  ...
}

public static Bar Create(int a, bool plusOrMinus) {
  if (plusOrMinus) {
    return new Bar(a, 5);
  } else {
    return new Bar(a, -5);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

2

You can just do it inline, no?

public Bar(int a, bool plusOrMinus) : base(a, plusOrMinus ? 5 : -5) {
}

If you need to do something more sophisticated, you can extract the logic out into a static method:

public Bar(int a, bool plusOrMinus) : base(a, GetValueFromPlusOrMinus(plusOrMinus)) {
}

public static int GetValueFromPlusOrMinus(bool plusOrMinus) 
{
    if (plusOrMinus)
        return 5;
    else
        return -5;
}

Comments

2

You can more or less do this if you can write a static function to process the data:

class Bar : Foo 
{
    public Bar(int a, bool plusOrMinus) : base(a, calc(plusOrMinus))
    {
    }

    private static calc(bool pom) : ...; return -5; }
}

Comments

1

My suggestion is to use composition instead of inheritence.

Instead of having a bunch of subclasses (A, B, C) derive from your base class (X), instead have A, B, C contain a private instance of X that they can call.

This way you only have the shared logic in one place (X) and all your classes are able to use it.

class Foo {
    private int c;

    public Foo(int a, int b) {
        c = a + b;
    }
}

class Bar {
    private Foo _base;

    public Bar(int a, bool plusOrMinus) {
        if (plusOrMinus) {
            _base = new Foo(a, 5);
        } else {
            _base = new Foo(a, -5);
        }
    }
}

Comments

1

How about this approach?

class Foo
{
    private int c;

    public Foo(Builder builder)
    {
        c = builder.A ?? 0 + builder.B ?? 0;
    }
}

class Bar : Foo
{
    public Bar()
        : base(new Builder().WithA(2).WithB(3).WithPlusOrMinus(false))
    {

    }
}


public class Builder
{
    public int? A { get; private set; }
    public int? B { get; private set; }
    public bool? PlusOrMinus { get; private set; }

    public Builder WithA(int a)
    {
        A = a;
        return this;
    }

    public Builder WithB(int b)
    {
        B = b;
        return this;
    }

    public Builder WithPlusOrMinus(bool plusOrMinus)
    {
        if(!plusOrMinus)
        {
            B *= -1;
        }
        return this;
    }
}

Comments

1

I would prefer making a protected Initialize(...) on the base class and call this at the end of the ctr in the inherited class.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.