在发送到Base构造函数之前修改参数值

时间:2009-10-30 18:10:52

标签: c# inheritance constructor

标题可能有点含糊不清,但我想不出更好的方法来说明这一点。

我意识到在调用基础构造函数之前我无法调用派生构造函数,但是我可以在将它们传递给基础之前以某种方式修改/创建参数值吗?

例如,

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.Numberint有效),有没有办法修改和/或创建在派生构造函数执行之前传递给基础构造函数的值?

7 个答案:

答案 0 :(得分:49)

我希望你可以在基类构造函数的参数列表中调用静态方法。

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

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

答案 1 :(得分:5)

您可以使用静态方法计算要传递给基础构造函数的值。

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

答案 2 :(得分: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);
    }
}

答案 3 :(得分:2)

是。可以使用不访问实例的普通表达式来操作该值。例如

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

答案 4 :(得分:1)

在不引入单独的静态方法的情况下,在base()子句中放置任意逻辑的一种方法是使用lambda或匿名委托。 base()中的表达式在所有构造函数参数的范围内,因此您可以在lambda中自由使用它们。例如。 (假设这是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个。

答案 5 :(得分:0)

没有

基础构造函数在DerivedClass构造函数中的任何逻辑之前运行,因此无法注入逻辑。

但是,您可以运行基类构造函数,然后在dervied类的构造函数中设置基类中的属性,以便更改值。

答案 6 :(得分:0)

你说

  

我意识到在调用基础构造函数

之前我无法调用派生构造函数

但是你显示了这段代码

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

当输入该代码块时,您的基类构造函数已经运行。但是,您可以在将表达式传递给基础构造函数之前修改表达式中的值(具有一些明显的约束)。但是,除非是构造函数的输入,否则您将无法访问“value”。