我有一定数量的类继承自抽象类:
abstract public class baseClass
{
//logics
}
public class child1 : baseClass
{
}
public class child2 : baseClass
{
}
现在我有一些管理类,它必须创建这些类中的一个,具体取决于一个枚举,它将具有相同名称的值,如下所示:
public enum ClassType
{
child1,
child2
}
public class Manager
{
private List<baseClass> _workers;
public void Initialize(ClassType type)
{
//what logics to put here? (resulting in correctChild)
_workers.Add(correctChild);
}
}
我在考虑使用typeof但不知道如何实现它。 注意:在这个例子中它是2个类,但在实际情况下,它是任意数量的类。
答案 0 :(得分:6)
使用命名的程序集和默认构造函数创建指定了其名称的类型的实例。
因此代码看起来像
Activator.CreateInstance(type.ToString(),assemblyName);
我实际上熟悉这样的实现,我自己也用过它。 我还建议查看this article,它解释了如何在枚举值上实际使用属性,以存储实际的类名。您甚至可以将其用作扩展名。
public static string Description(this Enum enumValue) {
Type enumType = enumValue.GetType();
FieldInfo field = enumType.GetField(enumValue.ToString());
object[] attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length == 0 ? enumValue.ToString() : ((DescriptionAttribute)attributes[0]).Description;
}
代码看起来像
Activator.CreateInstance(classType.Description(), assemblyName);
答案 1 :(得分:1)
如果您不需要属性开销并且从同一个程序集运行它 - 您可以使用执行程序集通过反射加载类型。 Activator.CreateInstance
可以动态地为您构建对象。
public class Manager
{
private List<baseClass> _workers = new List<baseClass>();
public void Initialize(ClassType type)
{
string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
Type objType = Type.GetType(string.Format("{0}.{1},{0}", assemblyName, type.ToString()));
var correctChild = (baseClass)Activator.CreateInstance(objType);
_workers.Add(correctChild);
}
}
答案 2 :(得分:0)
有很多方法可以区分不同类型。
您可以使用is
运算符
var o = ...;
if (o is Child1) {}
或者您可以使用as
运算符
var child = o as Child1;
if (child != null) {}
或您自己描述的内容,typeof
运算符。
我感觉到的是,如果你非常需要打字,那么可能还有其他的东西。也许你可以通过Polymorphism解决问题。然后,您不必区分冗长的if-else
或case-switch
构造中的所有不同类型,但您可以将“不同行为”委派给您的子类。
答案 3 :(得分:0)
如果你不想使用if语句,你可以使用case语句吗?像:
public class Manager
{
private List<baseClass> _workers;
public void Initialize(ClassType type)
{
switch (type)
{
case child1:
_workers.Add(correctChild);
break;
case child2:
_workers.Add(correctChild);
break;
}
}
}