Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

abstracting class instantiation

I have a base abstract class with several classes which extend and override it, however they all have the same constructor. Right now I call each constructor from a switch statement:

case 1: return new A(arg1); // arg is int

etc., for about 10 classes. Is there a way with generics or delegates to make one method which would take a classname and instantiate that type with the arguments?

This would help, since if I make a change to the constructors I also have to change each instantiation.

A delegate would be most straight-forward but research says no to assigning constructors to delegates.

ADDITION: I am now on wifi with my laptop and not just my cell, so here comes some code.

This is an example of what happens now:

switch (new Random().Next(4))
{
    case 3:
         // classA : baseClass, args{int, bool, otherClass}
         return new classA(arg1, arg2, arg3);
    case 2:
         // classB : baseClass, args{int, bool, otherClass}
         return new classB(arg1, arg2, arg3);
    case 1:
         // classC : baseClass, args{int, bool, otherClass}
         return new classC(arg1, arg2, arg3);
    case 0:
         // classD : baseClass, args{int, bool, otherClass}
         return new classD(arg1, arg2, arg3);
    default:
         continue;
}

I would like to call one instantiator at the end of the block with the three arguments.

A solution I thought of is to make and instantiator class that works similar to this:

ClassInstantiator inst = new ClassInstantiator(arg1, arg2, arg3);
switch(new Random().Next(4))
{
     case 4:
         return inst.instantiate<classA>();
     ...
}

Is this already built in to the language, or does anyone know of a more elegant solution?

like image 803
jeubank12 Avatar asked Dec 22 '22 04:12

jeubank12


1 Answers

The only constructor-related constraint you can put on a generic type is the new() constraint, which requires a public parameterless constructor.

You could use reflection; the example assumes that all the related types have a constructor taking an int, as in your example, and that the abstract base class is called B:

public T CreateInstance<T>(int i) where T : B
{
    return (T)Activator.CreateInstance(typeof(T), i);
}

Then you'd call it like this:

A a = CreateInstance<A>(3);
like image 197
phoog Avatar answered Dec 23 '22 18:12

phoog