Изменение значений параметров перед отправкой в ​​конструктор Base - PullRequest
29 голосов
/ 30 октября 2009

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

Я понимаю, что не могу вызвать производный конструктор до вызова базового конструктора, но могу ли я как-то изменить / создать значения параметров перед передачей их в базу?

Например,

public enum InputType
{
    Number = 1,
    String = 2,
    Date = 3
}

public class BaseClass
{
    public BaseClass(InputType t)
    {
        // Logic
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass(int i)
        : base(value)
    // Can I do something to infer what value should be here?
    {
        // Logic
    }
}

Если у меня есть производный класс, который может вывести значение, требуемое для базового конструктора (в этом примере InputType.Number будет действительным для int,), существует ли способ изменить и / или создать значения, которые передан базовому конструктору до выполнения производного конструктора?

Ответы [ 7 ]

49 голосов
/ 30 октября 2009

Полагаю, вы можете вызывать статические методы в списке параметров конструктора базового класса.

public class DerivedClass : BaseClass
{
    public DerivedClass(int i)
        : base(ChooseInputType(i))
    {
    }

    private static InputType ChooseInputType(int i)
    {
        // Logic
        return InputType.Number;
    }
}
5 голосов
/ 30 октября 2009

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

public class DerivedClass :
    BaseClass
{
    public
    DerivedClass(int i) :
        base(ComputedValue(i))
    {
    }

    public static InputType
    ComputedValue(int i)
    {
        return InputType.Number; // or any other computation you want here
    }
}
3 голосов
/ 30 октября 2009

Вы можете создать статический метод для производного класса и поместить туда свою логику:

public enum InputType {
    Number = 1,
    String = 2,
    Date = 3
}

public class BaseClass {
    public BaseClass(InputType t) {
        // Logic
    }
}

public class DerivedClass : BaseClass {
    public DerivedClass(int i)
        : base(GetInputType(i)) {
        // Is it possible to set "value" here?
        // Logic
    }

    private static InputType GetInputType(Int32 parameter) {
        // Do something with parameter
        // and return an InputType

        return (InputType)Enum.Parse(typeof(InputType), parameter);
    }
}
2 голосов
/ 30 октября 2009

Да. Для манипулирования значением нормально использовать нормальные выражения, которые не обращаются к экземпляру. Например

public DerivedClass(int i)
    : base((InputType)i)
{
}
1 голос
/ 30 октября 2009

Один способ взломать произвольную логику в предложении base() без введения отдельного статического метода - это использование лямбда-выражения или анонимного делегата. Выражение внутри base() находится в области действия всех параметров конструктора, поэтому вы можете свободно использовать их внутри лямбда-выражения. Например. (допустим, это C # 2.0, поэтому нет LINQ для написания однострочного текста для одной и той же вещи):

class Base
{
    public Base(int[] xs) {}
}

class Derived : Base
{
    public Derived(int first, int last)
        : base(
            ((Func<int[]>)delegate
            {
                List<int> xs = new List<int>();
                for (int x = first; x < last; ++x)
                {
                    xs.Add(x);
                }
                return xs.ToArray();
            })())
    {
    }
}

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

0 голосов
/ 30 октября 2009

Вы говорите

Я понимаю, что не могу вызвать производный конструктор до вызова базового конструктора

Но тогда вы показываете этот код

public DerivedClass(int i)
    : base(value)
{
    // Is it possible to set "value" here?
    // Logic
}

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

0 голосов
/ 30 октября 2009

номер

Базовый конструктор запускается до какой-либо логики в конструкторе DerivedClass, поэтому нет способа внедрить логику.

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

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