Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying parameter values before sending to Base constructor

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 constructor, but can I somehow modify/create parameters values prior to passing them to the base?

For example,

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

If I have a derived class that can infer the value required for the base constructor (in this example, InputType.Number would be valid for an int,) is there a way to modify and/or create values that are passed to the base constructor prior to the derived constructor executing?

like image 258
Ian P Avatar asked Oct 30 '09 18:10

Ian P


People also ask

Can we pass parameters to base class constructor?

To pass arguments to a constructor in a base class, use an expanded form of the derived class' constructor declaration, which passes arguments along to one or more base class constructors. Here, base1 through baseN are the names of the base classes inherited by the derived class.

What parameters are required to be passed to a class constructor?

This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer.

How do you pass value from the constructor of a child class to the constructor of a base class in C#?

If we want to pass arguments to the base class's constructor from the constructor of the child class, we have to use the base keyword in C#. The base keyword specifies which constructor of the base class should be called when an instance of the child class is created.


4 Answers

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;     } } 
like image 59
Don Kirkby Avatar answered Sep 23 '22 10:09

Don Kirkby


You can use a static method to compute a value to pass to the base constructor.

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     } } 
like image 44
GBegen Avatar answered Sep 23 '22 10:09

GBegen


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.

like image 42
Pavel Minaev Avatar answered Sep 26 '22 10:09

Pavel Minaev


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)
{
}
like image 21
JaredPar Avatar answered Sep 22 '22 10:09

JaredPar