Reputation: 5083
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
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
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
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
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