Tengo un proyecto C # para ProjectEuler si lo sabes.
Para eso uso una clase abstracta, llamémosla 'X'
public abstract class X {
protected abstract void SomeFunction()
}
Hay más de 600 problemas para resolver en este proyecto. Para cada problema, creo una clase que hereda de X. El nombre de la clase siempre es 'Baseclassname' seguido de un número
Exampel:
public class X2 : X {
public override void SomeFunction()
}
Durante el tiempo de ejecución, elijo a través de la consola ingresar un problema al ingresar un número entero válido. Este número entero entra en un interruptor y crea el problema correspondiente y ejecuta alguna función si '_problema' no es igual a nulo.
X _problem = null;
int someInput; //any valid input readin via Console
switch(someInput)
{
case 1:
_problem = new X1();
break;
case 2:
_problem = new X2();
break;
.
.
.
case 610:
_problem = new X610();
break;
}
_promblem?.someFunction();
Entonces, mi pregunta a la comunidad es cómo evitar un caso de cambio con más de 600 casos. ¿Hay una mejor solución para hacer esto?
Espero que esta pregunta esté bien escrita porque es la primera. :)
Editar: alguna matriz de pares 'clave, valor' solo sería ideal si todos los pares existentes se agregan automáticamente durante la compilación.
3 respuestas
Pruebe la reflexión de la siguiente manera;
X _problem = null;
int someInput; //any valid input readin via Console
try
{
_problem = Assembly.GetExecutingAssembly().CreateInstance($«X{someInput}») as X
}
catch{}
_promblem?.someFunction();
Aquí hay un esqueleto de lo que podría hacer con un menú de opciones para el usuario:
//Get all the types that inherit from 'X'
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(X)))
.ToList();
Console.WriteLine("Choose a class to run");
var index = 0;
foreach (var type in types)
{
Console.WriteLine($"{index++}: {type.Name}");
}
Console.Write("Enter number: ");
//Much better to use "TryParse" here and validate the input
index = int.Parse(Console.ReadLine());
var instance = (X)Activator.CreateInstance(types[index]);
instance.SomeFunction();
Tenga en cuenta que deberá cambiar el nivel de protección a public
para que esto funcione.
Si los nombres están bien formados (es decir, puede generar el nombre de la clase a partir de la entrada), sería fácil utilizar el método CreateInstance de System.Reflection.Assembly y luego enviarlo a su tipo abstracto y llamar al miembro base.
Preguntas relacionadas
Nuevas preguntas
c#
C # (pronunciado "see sharp") es un lenguaje de programación multi-paradigma de alto nivel, estáticamente tipado desarrollado por Microsoft. El código C # generalmente se dirige a la familia de herramientas y tiempos de ejecución .NET de Microsoft, que incluyen .NET Framework, .NET Core y Xamarin, entre otros. Use esta etiqueta para preguntas sobre el código escrito en las especificaciones formales de C # o C #.