7

I am having the following problem:

public class A {
    public A(X, Y, Z) {
    ...
    }
}

public class B : A {
    public B(X, Y) : base(X, Y) {
        //i want to instantiate Z here and only then pass it to the base class!
    }
}

How can I solve this problem? Is there a way?

3
  • What? is B:A? If so, how can A have more data than B? Also, A doesn't seem to have such a constructor... Commented Nov 18, 2010 at 10:18
  • Do you mean public class B : A { in your example? Commented Nov 18, 2010 at 10:18
  • Edited original post. Yes, its B: A Commented Nov 18, 2010 at 10:19

4 Answers 4

13

The common solution is to call a static method belonging to the type that can calculate the value of the parameter to be passed to the base constructor.

For example:

public B(int x, int y)
    : base(x, y, CalculateZ(x, y))
{

}

// You can make this parameterless if it does not depend on X and Y
private static int CalculateZ(int x, int y)
{
   //Calculate it here.

    int exampleZ = x + y;

    return exampleZ;
}

Do note that CalculateZ cannot be an instance method, because the this reference is not available in constructor initializers.

From the language-specification 10.11.1 Constructor initializers:

An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name.

EDIT: Changed 'instance' to 'static' in the description.

Sign up to request clarification or add additional context in comments.

2 Comments

+1, but don't you mean that it's legal to call static methods?
@Kobi, @LukeH: Was a brain-freeze typo; the mind thinks one thing and the fingers type another. Thanks for pointing it out.
2

You need to calculate Z before the constructor itself gets called. If it's simple you can use an inline expression, else you'll need to define a helper function.

Using a helperfunction:

public class A {
    public A(X x, Y y, Z z) {
    ...
    }
}

public class B : A {
    private static Z calculateZ()
    {
    }

    public B(X x, Y y) : base(X, Y, calculateZ()) {

    }
}

Without helperfunction:

public B(X, Y) : base(X, Y, X+Y) {

}

Comments

1
public abstract class A {
    public A(X, Y) {
    ...
    }

    public abstract Z TheVariableZ{get;set;}
}

public class B : A {
    public B(X, Y) : base(X, Y) {
        //i can only calculate Z here!
    }

    public override Z TheVariableZ{//implement it here}
}

And if you can't make A abstract, just mark the property as virtual

1 Comment

Calling a virtual method in a constructor is a bad idea: msdn.microsoft.com/en-us/library/ms182331(v=VS.100).aspx
1

Possibly this:

public abstract class A {
    public A(X, Y) {
       CalculateZ();
    }

    abstract void CalculateZ();
}

public class B : A {
    public B(X, Y) : base(X, Y) {

    }

    override void CalculateZ()
   {
      ... Calculate here.
   }
}

1 Comment

Calling a virtual method in a constructor is a bad idea: msdn.microsoft.com/en-us/library/ms182331(v=VS.100).aspx

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.