Как обрабатывать конструкторы базового класса в C #? - PullRequest
3 голосов
/ 28 октября 2011

У меня есть класс, который расширяет базовый класс.Базовый класс является более общим и, следовательно, нуждается в большем количестве параметров.Производный класс является особым типом базового класса, и, таким образом, ему нужен только один из двух параметров, который базовому классу нужен в его конструкторе (производный класс может предоставить базовому классу второй параметр, но сначала ему необходимо выполнить некоторую обработку).

Возможно ли иметь конструктор в производном классе, который затем вызывает конструктор базовых классов?

Я знаю, что мог бы просто использовать : base(int a, int b), если параметры были переданы напрямую,но я не думаю, что смогу сделать это, поскольку мне нужно обработать вторую переменную перед вызовом конструктора базового класса.

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

Ответы [ 6 ]

4 голосов
/ 28 октября 2011

Один из способов сделать это - использовать троичный оператор

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

Для более сложных условных выражений, хотя вы должны перейти к статическому заводскому методу

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);
  }
}
2 голосов
/ 28 октября 2011

Вы можете сделать это более или менее, если можете написать статическую функцию для обработки данных:

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

    private static calc(bool pom) : ...; return -5; }
}
2 голосов
/ 28 октября 2011

Вы можете просто сделать это встроенным, нет?

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

Если вам нужно сделать что-то более сложное, вы можете извлечь логику в метод static :

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

public static int GetValueFromPlusOrMinus(bool plusOrMinus) 
{
    if (plusOrMinus)
        return 5;
    else
        return -5;
}
1 голос
/ 28 октября 2011

Я бы предпочел сделать защищенную Initialize (...) для базового класса и вызывать ее в конце ctr унаследованного класса.

1 голос
/ 28 октября 2011

Как насчет этого подхода?

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;
    }
}
1 голос
/ 28 октября 2011

Я предлагаю использовать композицию вместо наследования.

Вместо того чтобы иметь подклассы (A, B, C), производные от вашего базового класса (X), вместо этого пусть A, B, C содержат частный экземпляр X, который они могут вызвать.

Таким образом, у вас есть общая логика только в одном месте (X), и все ваши классы могут ее использовать.

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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...