callisto
callisto

Reputation: 5083

Overloading a method based on parameter value?

I have a class and I want the class constructor to vary according to the value of the first parameter.

  public class Calc
    {
        public Calc( Operator calcOpr = Operator.Concat, string sourceName, string newString )
        {
            calcOperator = calcOpr;
            sourceType = dataType;
        }

        public Calc( Operator calcOpr = Operator.PadLeft,  int startindex, int  count )
        {
            calcOperator = calcOpr;
            sourceType = dataType;
        }

Now I KNOW the above is not valid code, but as pseudocode it does show what I want to achieve.
Is there some way of getting class constructors overloaded based on the parameter values?

EDIT: I want to do this so that that the parameters required when instantiating the class are changed according to different Operator values.

Upvotes: 2

Views: 1451

Answers (4)

gjvdkamp
gjvdkamp

Reputation: 10516

The example code is a bit off, since they both have a different signature (string vs int for the second argument). So passing and int or string would already select the right overload.

When you want different behaviour with the same method signature, just switch on the enum:

switch(calcOpr){
  case Operator.Concat: 
    calcOperator = calcOpr;
    sourceType = dataType;
    break;

  case Operator.Padleft: 
    calcOperator = calcOpr;
    sourceType = dataType;
    break;

  default: 
    // throw error?

}

Edit (to your edit)

A method has a fixed signature, so if you'd want to have 1 constructor that creates the right type based on the Operator, you'd have t pass all possible arguments in there. (bad code) :

public Calc( Operator calcOpr, string sourceName, string newString,  int startindex, int  count )
{
  switch(calcOpr){
    case Operator.Concat: 
       // validate sourceName and newString

    case Operator.Padleft
       // validate startindex and count

}

Doesn't smell good.

I think I would go for separate method instead of constructor overloads. (Static so you can call them from the type)

public static Calc GetConcat(string SourceName, string newString){
  Class c = new Class();
  c.calcOperator = Operator.Concat;
  c.sourcetype = dataType; //where does this one come from? 
  //etc..
  return c;
}

public static Calc GetPadLeft(int startindex, int  count){
  Class c = new Class();
  c.calcOperator = Operator.PadLeft;
  c.sourcetype = dataType; //where does this one come from? 
  // etc
  return c;
}

Also you may want to look into creating derived classes for Concat and PadLeft that derive from Calc and overload methods/ add specific properties. Actually I think that's what I would do but you'd have to tell a bit more about what you're doing exactly.

Upvotes: 1

ferosekhanj
ferosekhanj

Reputation: 1074

May be You can try a constrcutor with variable arguments.

public class Calc
{
    public Calc( Operator calcOpr, params object[] values)
    {
    switch(op)
    {
    case Op.CONCAT:
        Concat(values[0],values[1]);
    case Op.PADLEFT:
        PadLeft(values[0],values[1],values[2]);
    }
    }

    public void Concat(string str1, string str2)
    {
    }
    public void PadLeft(string str1, int startindex, int  count )
    {
    }

Upvotes: 0

bruno conde
bruno conde

Reputation: 48265

I think that a good pattern to use here would be a factory.

A CalcFactory would allow callers to know explicitly the concrete objective of the Calc.

public static class CalcFactory
{
   public static Calc createConcatCalc(string sourceName, string newString)
   {
       // call explicit constructors
   }

   public static Calc createPadLeftCalc(int startindex, int count)
   {
       // call explicit constructors
   }
}

This factory could use @Roflcoptr's constructors internally.

Upvotes: 1

anon
anon

Reputation:

You could implement it that way:

public class Calc
    {
        public Calc(string sourceName, string newString )
        {
            calcOperator = Operator.Concat;
            sourceType = dataType;
        }

        public Calc(int startindex, int  count )
        {
            calcOperator = Operator.PadLeft;
            sourceType = dataType;
        }
}

Upvotes: 1

Related Questions