Modifying parameter values before sending to Base constructor

前端 未结 7 512
借酒劲吻你
借酒劲吻你 2021-01-07 16:26

The title may be a bit ambiguous, but I couldn\'t think of a better way to word this.

I realize that I can not call a derived constructor prior to calling a base con

相关标签:
7条回答
  • 2021-01-07 16:52

    One hack to put arbitrary logic in base() clause without introducing a separate static method is to use a lambda or anonymous delegate. The expression inside base() is in scope of all constructor parameters, so you can freely use them inside the lambda. E.g. (let's say this is C# 2.0, so there's no LINQ to write a single-liner for the same thing):

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

    However, I would strongly advise against using this in practice, because from readability point of view this is really horrible. With a static method you'll need to explicitly pass constructor arguments to it, but it's not like you normally have more than 3-4 of those.

    0 讨论(0)
  • 2021-01-07 17:00

    I expect you could call static methods in the parameter list of the base class constructor.

    public class DerivedClass : BaseClass
    {
        public DerivedClass(int i)
            : base(ChooseInputType(i))
        {
        }
    
        private static InputType ChooseInputType(int i)
        {
            // Logic
            return InputType.Number;
        }
    }
    
    0 讨论(0)
  • 2021-01-07 17:00

    Yes. It's fine to use normal expressions, which don't access the instance, in order to manipulate the value. For instance

    public DerivedClass(int i)
        : base((InputType)i)
    {
    }
    
    0 讨论(0)
  • 2021-01-07 17:00

    You say

    I realize that I can not call a derived constructor prior to calling a base constructor

    But then you show this code

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

    When that code block is entered you base class constructor has already run. You can however modify the value in an expression before passing it to the base constructor (with some obvious constraints). However, you will not have access to 'value' unless it is an input to the constructor.

    0 讨论(0)
  • 2021-01-07 17:09

    You can create a static method on derived class and put your logic there:

    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);
        }
    }
    
    0 讨论(0)
  • 2021-01-07 17:10

    No.

    The base constructor is run prior to any logic in the DerivedClass constructor, so there is no way to inject logic.

    You can, however, run the base class constructor, then set properties in the base class during the dervied class's constructor in order to change values.

    0 讨论(0)
提交回复
热议问题