TweeZz
TweeZz

Reputation: 4919

Is there a way to _somehow_ use an enum value to pass a method call as a generic parameter of that method?

(The question might not make enough sense. It was hard to write it. Feel free to update it if you can make it more clear.)

I have an enum:

public enum nodeTypes 
{ 
    Part = 1, 
    SelectListValue, 
    MultiSelectListValue, 
    RepeatingPart,
    ...
}

And a method with a switch case:

switch (type)
{
    case nodeTypes.SelectListValue:
        GenerateSubNode<SelectListValue>(parent, root, depth, true);
        break;
    case nodeTypes.MultiSelectListValue:
        GenerateSubNode<MultiSelectListValue>(parent, root, depth, true);
        break;
    case nodeTypes.Part:
        GenerateSubNode<Part>(parent, root, depth, true);
        break;
    case ....
 }

And another method:

private void GenerateSubNode<ComponentType>(Container parent, ZForm root, int depth, bool isContainer) where ComponentType : Component, new()
{
    ...
    var c = new ComponentType();
    ...
}

Is there a way to write that switch case statement as a 1 liner? It feels like repetitive code.

Upvotes: 1

Views: 106

Answers (3)

MBen
MBen

Reputation: 3996

May be you could try something like WRONG:

    List<ComponentType> types = new List { SelectListValue, MultiSelectValue,...}
    ....
    CompenentType type = types[(int)type];
    GenerateSubNode<type>(parent, root,depth, true);

Or you could this with the factory pattern.

Edit after good comments :

class VehiculeCreation
{ public static List<Type> vehicules = new List<Type> { typeof(Car), typeof(motor) };
enum Vehicule 
{
    Car = 0,
    Motor = 1,
};


static void Main()
{
    vehicule cars = GenerateVehicules((int)Vehicule.Car);
    vehicule motors = GenerateVehicules((int)Vehicule.Motor);
    cars.print();
    motors.print();

    Console.ReadLine();
}

public abstract class vehicule
{
    public abstract void print();
}

public class Car : vehicule
{
    public override void print() {Console.WriteLine("I am a car");}
}

public class motor : vehicule
{
    public override void print() { Console.WriteLine("I am a motor"); }
}

public static vehicule GenerateVehicules(int index)
{
    return (vehicule)System.Activator.CreateInstance(vehicules[index]);
}

}

Upvotes: 1

aL3891
aL3891

Reputation: 6275

You can do this with reflection as well:

typeof( ClassWhereGenerateSubNodeMethodIs ) //alternativly, this.GetType()
   .GetMethod( "GenerateSubNode" )
   .MakeGenericMethod( Type.GetType( "namespace.where.type.classes.are." + type.ToString() ) )
   .Invoke( this, new object[ ] { parent, root, depth, true} );

this that is passed to Invoke is the instance on witch GenerateSubNode is called, if GenerateSubNode was static, you'd pass in null here.

Upvotes: 1

Euphoric
Euphoric

Reputation: 12849

Something like this?

Dictionary<nodeTypes, Action<Container, ZForm, int, bool>> generateActions = new Dictionary<nodeTypes, Action<Container, ZForm, int, bool>>
{ 
  {nodeTypes.SelectListValue, GenerateSubNode<SelectListValue> },
  {nodeTypes.MultiSelectListValue, GenerateSubNode<MultiSelectListValue> },
  // .. so on
}

Then use it:

generateActions[type](parent, root, depth, true);
// todo: does action exist? validation

Upvotes: 0

Related Questions