C# select Class 在运行时
C# select Class during Runtime
我有一个 ProjectEuler 的 C# 项目,如果你知道的话。
为此我使用了一个抽象 class 让我们称之为 'X'
public abstract class X {
protected abstract void SomeFunction()
}
这个项目中有 600 多个问题需要解决。对于每个问题,我创建一个继承自 X 的 class。class 的名称始终是 'Baseclassname' 后跟数字
示例:
public class X2 : X {
public override void SomeFunction()
}
在运行时,我通过控制台输入一个有效整数来选择一个问题。如果“_problem”不等于 null,则此整数进入开关并创建相应的问题并执行 someFunction。
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();
所以我向社区提出的问题是如何避免超过 600 个案例的切换案例。有更好的解决方案吗?
我希望这个问题写得好,因为这是我的第一个问题。 :)
编辑:一些 'key, value' 对数组只有在编译期间自动添加所有现有对时才是理想的。
如果名称格式正确(即您可以从输入生成 class 名称),使用 System.Reflection.Assembly 的 CreateInstance 方法然后转换为您的抽象类型将很容易并调用基本成员。
尝试如下反射;
X _problem = null;
int someInput; //any valid input readin via Console
try
{
_problem = Assembly.GetExecutingAssembly().CreateInstance($«X{someInput}») as X
}
catch{}
_promblem?.someFunction();
以下是您可以使用供用户选择的菜单执行的操作的框架:
//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();
请注意,您必须将保护级别更改为 public
才能正常运行。
我有一个 ProjectEuler 的 C# 项目,如果你知道的话。
为此我使用了一个抽象 class 让我们称之为 'X'
public abstract class X {
protected abstract void SomeFunction()
}
这个项目中有 600 多个问题需要解决。对于每个问题,我创建一个继承自 X 的 class。class 的名称始终是 'Baseclassname' 后跟数字
示例:
public class X2 : X {
public override void SomeFunction()
}
在运行时,我通过控制台输入一个有效整数来选择一个问题。如果“_problem”不等于 null,则此整数进入开关并创建相应的问题并执行 someFunction。
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();
所以我向社区提出的问题是如何避免超过 600 个案例的切换案例。有更好的解决方案吗?
我希望这个问题写得好,因为这是我的第一个问题。 :)
编辑:一些 'key, value' 对数组只有在编译期间自动添加所有现有对时才是理想的。
如果名称格式正确(即您可以从输入生成 class 名称),使用 System.Reflection.Assembly 的 CreateInstance 方法然后转换为您的抽象类型将很容易并调用基本成员。
尝试如下反射;
X _problem = null;
int someInput; //any valid input readin via Console
try
{
_problem = Assembly.GetExecutingAssembly().CreateInstance($«X{someInput}») as X
}
catch{}
_promblem?.someFunction();
以下是您可以使用供用户选择的菜单执行的操作的框架:
//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();
请注意,您必须将保护级别更改为 public
才能正常运行。