Не могу сказать, что понимаю логику, которая заставляет вас выбирать этот странный дизайн, но я могу придумать, по крайней мере, два пути его улучшения, при условии, что все функции, которые вы вызываете, реализованы в базовом классе (и переопределяют конечно, при необходимости в производных классах).
Оба решения актуальны только в том случае, если все классы предоставляют конструктор без параметров и функции без параметров, а выполнение функций не требует дальнейшей инициализации:
Первое решение потребовало бы, чтобы вы изменили сигнатуру метода и заставили вызывающий метод знать типы классов, чтобы вы не смогли реализовать его, но в нем задействовано гораздо меньше кода.
ExecuteMethod<TClass>(Func<TClass, string> func) where T: BaseClass, new()
(
return func(new T());
)
И вы называете это так:
var result = ExecuteMethod<ClassA>(a => a.Function1);
Второе решение
Это может быть более подходящим для ваших нужд:
Вам нужно будет создать два словаря и заполнить их, например:
private Dictionary<int, Func<ParentClass>> constructors = new Dictionary<int, Func<ParentClass>>()
{
{1, () => new ClassA()},
{2, () => new ClassB()}
// more of the same
};
private Dictionary<int, Func<ParentClass, string>> methods = new Dictionary<int, Func<ParentClass, string>>()
{
{1, i => i.function1},
{2, i => i.function2}
// more of the same
};
Тогда ваш метод все еще может взять два целых числа и вернуть строку:
string DoSomething(int classType, int function)
{
var instance = constructors[classType].Invoke();
return methods[function].Invoke(instance);
}
Обратите внимание, что код написан прямо здесь и не проверен, поэтому я мог пропустить одну или две вещи, но это общая идея.