Проблема с конструкторами и наследованием в C # - PullRequest
7 голосов
/ 18 ноября 2010

У меня возникла следующая проблема:

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!
    }
}

Как я могу решить эту проблему?Есть ли способ?

Ответы [ 4 ]

13 голосов
/ 18 ноября 2010

Общим решением является вызов статического метода, принадлежащего типу, который может вычислить значение параметра, передаваемого в базовый конструктор.

Например:

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;
}

Обратите внимание, что CalculateZ не может быть методом экземпляра, поскольку ссылка this недоступна в инициализаторах конструктора.

Из спецификации языка 10.11.1 Инициализаторы конструктора:

Инициализатор конструктора экземпляра не может получить доступ к создаваемому экземпляру.Следовательно, это ошибка времени компиляции, чтобы ссылаться на это в выражении аргумента инициализатора конструктора, так же как и ошибка времени компиляции для выражения аргумента, чтобы ссылаться на любой элемент экземпляра через простое имя.

РЕДАКТИРОВАТЬ: в описании изменено «экземпляр» на «статический».

2 голосов
/ 18 ноября 2010

Вам нужно вычислить Z до вызова самого конструктора.Если это просто, вы можете использовать встроенное выражение, иначе вам нужно определить вспомогательную функцию.

Использование вспомогательной функции:

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()) {

    }
}

Без вспомогательной функции:

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

}
1 голос
/ 18 ноября 2010

Возможно это:

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 голос
/ 18 ноября 2010
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}
}

А если вы не можете сделать реферат, просто пометьте свойство как виртуальное

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...