Class abstraction

I have a base abstract class with several classes that extend and override it, however they all have the same constructor. Right now, I am invoking every constructor from the 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 that will take a class name and create an instance of this type with arguments?

This will help, because if I make changes to the constructors, I must also change each creation.

The delegate will be most frank, but the study does not talk about the appointment of constructors to delegates.

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

This is an example of what is happening 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 name one instance at the end of the block with three arguments.

The solution I was thinking about is the make and instantiator class, which works something like this:

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

Is it already built into the language, or does anyone know a more elegant solution?

+4
source share
4 answers

The only constructor-specific constraint you can use for a generic type is the new() constraint, which requires a public constructor with no parameters.

You can use reflection; the example assumes that all related types have a constructor that takes 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 would call it like this:

 A a = CreateInstance<A>(3); 
+5
source

You cannot escape the fact that something must decide on a conditional basis what to build, but you can encapsulate it. Can I introduce you one of the most popular GOF templates: http://en.wikipedia.org/wiki/Factory_method_pattern

eg.

 public abstract class MyBase(string name){} public class Concrete1 : MyBase{} public class Concrete2 : MyBase{} public class MyFactory { public MyBase Create(Criteria criteria) { //conditional logic/reflection } } 
+5
source

You can create a dictionary with the class name as the key and the constructor delegate as the value.

 Dictionary<string,Func<int,BaseClass>> _dict = new Dictionary<string,Func<int,BaseClass>>(); _dict.Add("ClassA", i => new ClassA(i)); _dict.Add("ClassB", i => new ClassB(i)); // Create ClassA object by class name BaseClass obj = _dict["ClassA"](5); 
+1
source

I don’t want to complicate your problem too much, but if you find that you have a lot of such code, you may be interested in using the IoC container.

Popular IoC Containers:

0
source

Source: https://habr.com/ru/post/1387251/


All Articles