Подтвердить что ты не робот

Изменение значений параметров перед отправкой в ​​конструктор базы

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

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

Например,

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), существует ли способ изменить и/или создать значения, которые передается базовому конструктору перед производным конструктором, выполняющим?

4b9b3361

Ответ 1

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

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

    private static InputType ChooseInputType(int i)
    {
        // Logic
        return InputType.Number;
    }
}

Ответ 2

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

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

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

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

Ответ 4

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

public DerivedClass(int i)
    : base((InputType)i)
{
}

Ответ 5

Один взломать произвольную логику в выражении base() без введения отдельного статического метода - использовать лямбда или анонимный делегат. Выражение внутри base() находится в пределах всех параметров конструктора, поэтому вы можете свободно использовать их внутри лямбда. Например. (скажем, это С# 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 таких.

Ответ 6

Нет.

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

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

Ответ 7

Вы говорите

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

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

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

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