得到一个没有很多if语句的类

我有一定数量的类inheritance自抽象类:

abstract public class baseClass { //logics } public class child1 : baseClass { } public class child2 : baseClass { } 

现在我有一些管理类,必须创建这些类中的一个,具体取决于枚举,它将具有相同名称的值,如下所示:

 public enum ClassType { child1, child2 } public class Manager { private List _workers; public void Initialize(ClassType type) { //what logics to put here? (resulting in correctChild) _workers.Add(correctChild); } } 

我在考虑使用typeof,但不知道如何实现它。 注意:在这个例子中它是2个类,但在实际情况下,它是任意数量的类。

如果您不需要属性的开销并且从同一个程序集运行它 – 您可以使用执行程序集通过reflection加载类型。 Activator.CreateInstance可以动态地为您构建对象。

 public class Manager { private List _workers = new List(); 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); } } 

看看Activator.CreateInstance()

使用命名的程序集和默认构造函数创建指定了其名称的类型的实例。

所以代码看起来像

 Activator.CreateInstance(type.ToString(),assemblyName); 

我实际上熟悉这样的实现,我自己也用过它。 我还建议查看这篇文章 ,解释如何在枚举值上实际使用属性,以存储实际的类名。 您甚至可以将其用作扩展程序。

  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); 

有很多种方法可以区分不同类型。

你可以使用is运算符

 var o = ...; if (o is Child1) {} 

或者您可以使用as运算符

 var child = o as Child1; if (child != null) {} 

或者你自己已经描述过的,类型操作符。

我感觉到的是,如果你非常需要类型铸造,那么可能还有其他的东西在手边。 也许你可以通过多态来解决你的问题。 然后,您不必在冗长的if-elsecase-switch结构中区分所有不同类型,但您可以将“不同行为”委托给您的子类。

如果您不想使用if语句,可以使用case语句吗? 喜欢:

 public class Manager { private List _workers; public void Initialize(ClassType type) { switch (type) { case child1: _workers.Add(correctChild); break; case child2: _workers.Add(correctChild); break; } } }